summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorroot <root@vps-18a7a2b7.vps.ovh.ca>2024-02-13 16:10:38 -0500
committerroot <root@vps-18a7a2b7.vps.ovh.ca>2024-02-13 16:10:38 -0500
commitb2dec60e05d38630d567900ef668aadf66ddfc33 (patch)
treedcee4b97a53333d6fc89eee14c024160fb65c992
parent482596890c808af2f47c8713d0e168e4f0d1ec42 (diff)
refactor like a mastor
-rwxr-xr-xsrc/mariadb-push-replica.sh161
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
141restore_from_backup() 141restore_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 ... .
325send_mariadb_dump() 342send_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
332pipe_into_mariadb() 351receive_mariadb_dump()
333{ 352{
334 pv -f | mariadb 353 pv -f | mariadb --skip-reconnect
335} 354}
336 355
337mariadbdump_transfer_missing_databases() 356save_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 372mariadb_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
392mariadbdump_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
413mariadbdump_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
424intersection_lines()
425{
426 comm -12 -- "$1" "$2"
427}
428
429subtract_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
376main() 437main()
@@ -398,8 +459,14 @@ list_databases()
398{ 459{
399mariadb -t "$@" <<. 460mariadb -t "$@" <<.
400select 461select
401 @@hostname, 462 @@hostname
402 @@server_id, 463, @@server_id
464, count(schema_name) as 'databases'
465, @@gtid_slave_pos
466from
467 information_schema.schemata
468;
469select
403 schema_name as 'database' 470 schema_name as 'database'
404from 471from
405 information_schema.schemata 472 information_schema.schemata