diff options
author | root <root@vps-18a7a2b7.vps.ovh.ca> | 2024-02-13 16:10:38 -0500 |
---|---|---|
committer | root <root@vps-18a7a2b7.vps.ovh.ca> | 2024-02-13 16:10:38 -0500 |
commit | b2dec60e05d38630d567900ef668aadf66ddfc33 (patch) | |
tree | dcee4b97a53333d6fc89eee14c024160fb65c992 | |
parent | 482596890c808af2f47c8713d0e168e4f0d1ec42 (diff) |
refactor like a mastor
-rwxr-xr-x | src/mariadb-push-replica.sh | 161 |
1 files changed, 114 insertions, 47 deletions
diff --git a/src/mariadb-push-replica.sh b/src/mariadb-push-replica.sh index 7134864..e133fad 100755 --- a/src/mariadb-push-replica.sh +++ b/src/mariadb-push-replica.sh | |||
@@ -124,18 +124,18 @@ stop_mariadb_server_and_remove_database_files() | |||
124 | { | 124 | { |
125 | livedb=/var/lib/mysql | 125 | livedb=/var/lib/mysql |
126 | set -e | 126 | set -e |
127 | if [ -e "$livedb" ] | 127 | set -o pipefail |
128 | [ -e "$livedb" ] || return 0 | ||
129 | |||
130 | if [ "$(systemctl is-active mariadb)" = active ] | ||
128 | then | 131 | then |
129 | if [ "$(systemctl is-active mariadb)" = active ] | 132 | systemctl stop mariadb |
130 | then | ||
131 | systemctl stop mariadb | ||
132 | fi | ||
133 | livedb_backup=$livedb~$(date -Ins) | ||
134 | mv -v -T -- "$livedb" "$livedb_backup" | ||
135 | mkdir "$livedb" | ||
136 | chown --reference="$livedb_backup" "$livedb" | ||
137 | chmod --reference="$livedb_backup" "$livedb" | ||
138 | fi | 133 | fi |
134 | livedb_backup=$livedb~$(date -Ins) | ||
135 | mv -v -T -- "$livedb" "$livedb_backup" | ||
136 | mkdir "$livedb" | ||
137 | chown --reference="$livedb_backup" "$livedb" | ||
138 | chmod --reference="$livedb_backup" "$livedb" | ||
139 | } | 139 | } |
140 | 140 | ||
141 | restore_from_backup() | 141 | restore_from_backup() |
@@ -321,56 +321,117 @@ printarray() | |||
321 | 321 | ||
322 | # Call run_replica from here to avoid | 322 | # Call run_replica from here to avoid |
323 | # piping the database back to caller | 323 | # piping the database back to caller |
324 | # unnecessarily | 324 | # unnecessarily. Better would be |
325 | # a direct connect from mariadb client | ||
326 | # to remote mariadb server; but that | ||
327 | # requires transmitting credentials. | ||
328 | # Credential-transporter. Transporter-transporter. | ||
329 | # Well, a transporter protein is more like a provenance tag, | ||
330 | # and the transporter code is the receptor to the transporter | ||
331 | # which is the provenance checker. But anyway we have that | ||
332 | # with ssh, except we don't: we are assuming the primary | ||
333 | # has the ssh root of the replica! Insanity! Now this only works | ||
334 | # because the code runs on the primary; unless we forward the | ||
335 | # ssh auth with the ssh agent; but that only makes the security | ||
336 | # flaw temporary not solved; in fact, the replica should receive | ||
337 | # the transmission on some limited authorization channel; which | ||
338 | # _could_ be ssh; in fact, the dump could transparently be either | ||
339 | # live or else cached on the server side; it could be the | ||
340 | # rsync.net backup even; but ... it needs to include | ||
341 | # the btrfs snap similarly ... . | ||
325 | send_mariadb_dump() | 342 | send_mariadb_dump() |
326 | { | 343 | { |
327 | (set -x | 344 | ( |
328 | mariadb-dump "${@:2}") | | 345 | set -x |
329 | replica_host="$1" run_replica pipe_into_mariadb | 346 | mariadb-dump "${@:2}" |
347 | ) | | ||
348 | replica_host="$1" run_replica receive_mariadb_dump | ||
330 | } | 349 | } |
331 | 350 | ||
332 | pipe_into_mariadb() | 351 | receive_mariadb_dump() |
333 | { | 352 | { |
334 | pv -f | mariadb | 353 | pv -f | mariadb --skip-reconnect |
335 | } | 354 | } |
336 | 355 | ||
337 | mariadbdump_transfer_missing_databases() | 356 | save_array() |
338 | { | 357 | { |
339 | declare -a primary_dbs | 358 | declare -n _to_save="$1" |
340 | mapfile -t primary_dbs < \ | 359 | case "$2 $3" in |
341 | <(</dev/null run_primary \ | 360 | 'from zfile' ) |
342 | mariadb_list_databases | sort -u) | 361 | mapfile -d '' -t _to_save < "$4" |
343 | 362 | ;; | |
344 | declare -a replica_dbs | 363 | 'from lines' ) |
345 | mapfile -t replica_dbs < \ | 364 | mapfile -t _to_save < "$4" |
346 | <(</dev/null run_replica \ | 365 | ;; |
347 | mariadb_list_databases | sort -u) | 366 | * ) |
367 | false | ||
368 | ;; | ||
369 | esac | ||
370 | } | ||
348 | 371 | ||
349 | declare -a dbs_missing_from_replica | 372 | mariadb_scan_databases() |
350 | mapfile -t dbs_missing_from_replica < \ | 373 | { |
351 | <(comm -23 -- \ | 374 | declare -g -a primary_dbs |
352 | <(printarray primary_dbs) \ | 375 | save_array primary_dbs from lines <( |
353 | <(printarray replica_dbs)) | 376 | run_primary mariadb_list_databases </dev/null | |
377 | sort -u | ||
378 | ) | ||
379 | |||
380 | declare -g -a replica_dbs | ||
381 | save_array replica_dbs from lines <( | ||
382 | run_replica mariadb_list_databases </dev/null | | ||
383 | sort -u | ||
384 | ) | ||
385 | |||
386 | declare -g -a primary_dbs_not_on_replica | ||
387 | save_array primary_dbs_not_on_replica from zfile <( | ||
388 | subtract_arrays primary_dbs replica_dbs | ||
389 | ) | ||
390 | } | ||
354 | 391 | ||
392 | mariadbdump_transfer_missing_databases() | ||
393 | { | ||
394 | mariadb_scan_databases | ||
355 | declare -a to_replicate | 395 | declare -a to_replicate |
356 | if [ $# = 0 ] | 396 | if [ $# = 0 ] |
357 | then | 397 | then |
358 | to_replicate=("${dbs_missing_from_replica[@]}") | 398 | to_replicate=("${primary_dbs_not_on_replica[@]}") |
399 | printf "Missing on ${replica_host}: %s\n" \ | ||
400 | "${to_replicate[@]}" | ||
401 | exit | ||
359 | else | 402 | else |
360 | mapfile -t to_replicate < \ | 403 | save_array to_replicate from lines \ |
361 | <(comm -12 -- \ | 404 | <(intersection_lines \ |
362 | <(printarray dbs_missing_from_replica) \ | 405 | <(printarray primary_dbs_not_on_replica) \ |
363 | <(printlines "$@")) | 406 | <(printlines "$@" | sort -u)) |
364 | fi | ||
365 | if [ ${#to_replicate[@]} -gt 0 ] | ||
366 | then | ||
367 | run_primary \ | ||
368 | send_mariadb_dump "$replica_host" \ | ||
369 | --master-data \ | ||
370 | --gtid \ | ||
371 | --single-transaction \ | ||
372 | --databases "${to_replicate[@]}" | ||
373 | fi | 407 | fi |
408 | mariadbdump_transfer_databases \ | ||
409 | "$replica_host" \ | ||
410 | "${to_replicate[@]}" | ||
411 | } | ||
412 | |||
413 | mariadbdump_transfer_databases() | ||
414 | { | ||
415 | [ $# -ge 2 ] || return | ||
416 | run_primary \ | ||
417 | send_mariadb_dump "$1" \ | ||
418 | --master-data \ | ||
419 | --gtid \ | ||
420 | --single-transaction \ | ||
421 | --databases "${@:2}" | ||
422 | } | ||
423 | |||
424 | intersection_lines() | ||
425 | { | ||
426 | comm -12 -- "$1" "$2" | ||
427 | } | ||
428 | |||
429 | subtract_arrays() | ||
430 | { | ||
431 | declare -n _a="$1" _b="$2" | ||
432 | comm -z -23 -- \ | ||
433 | <(printf '%s\0' "${_a[@]}") \ | ||
434 | <(printf '%s\0' "${_b[@]}") | ||
374 | } | 435 | } |
375 | 436 | ||
376 | main() | 437 | main() |
@@ -398,8 +459,14 @@ list_databases() | |||
398 | { | 459 | { |
399 | mariadb -t "$@" <<. | 460 | mariadb -t "$@" <<. |
400 | select | 461 | select |
401 | @@hostname, | 462 | @@hostname |
402 | @@server_id, | 463 | , @@server_id |
464 | , count(schema_name) as 'databases' | ||
465 | , @@gtid_slave_pos | ||
466 | from | ||
467 | information_schema.schemata | ||
468 | ; | ||
469 | select | ||
403 | schema_name as 'database' | 470 | schema_name as 'database' |
404 | from | 471 | from |
405 | information_schema.schemata | 472 | information_schema.schemata |