Назад | Перейти на главную страницу

Быстрая передача большей базы данных MySQL / MariaDB, сохранение и перезапуск

Мне нужно перенести сайт Drupal с БД MariaDB 43 ГБ через ssh / scp на другой сервер.

У меня ограниченное окно простоя рано утром. Раньше я передавал БД меньшего размера (<3 ГБ) напрямую через каналы следующим образом:

ssh -l webuser 10.0.0.99 "cd /var/www/drupal7/htdocs/site_name && drush sql-dump | xz -1 -" | xz -d - | drush sqlc

Но с этой более крупной БД меня беспокоит, что какая-то часть этого конвейера выйдет из строя, и мне придется перезапускать все заново, что почти наверняка будет означать, что я превыслю окно простоя.

Таким образом, очевидным решением было бы разделить его на отдельные независимые шаги, чтобы я мог переделывать части задачи в случае сбоя одного из них:

ssh -l webuser 10.0.0.99 "cd /var/www/drupal7/htdocs/site_name && drush sql-dump | xz -1 - > /home/webuser/db_dump.sql.xz"
scp webuser@10.0.0.99:/home/webuser/db_dump.sql.xz .
xzcat /home/webuser/db_dump.sql.xz | drush sqlc

Но теперь шаги являются последовательными и занимают больше времени, что означает меньше времени на повторение шага в случае, если что-то пошло не так.

Итак, я предполагаю, что я ищу способ создать дамп БД на старом сервере и иметь второй, независимый процесс, переносящий данные на новый сервер и запускающий восстановление БД на новом сервере.

Просто используя

scp webuser@10.0.0.99:/home/webuser/db_dump.sql.xz .

на еще не завершенном дампе БД не будет работать, поскольку scp не будет ждать, пока MariaDB закончит запись дампа БД.

Кто-нибудь знает команду, которая продолжает передачу или вывод данных до завершения дампа БД?

Или кто-то знает способ лучше перенести БД?


Обновить:

Я решил, что могу использовать tee команда вроде этой:

ssh -l webuser 10.0.0.99 "cd /var/www/drupal7/htdocs/site_name && drush sql-dump | xz -1 - | tee -a /home/webuser/db_dump.sql.xz" | xz -d - | drush sqlc

Это улучшило бы ситуацию, однако представьте себе ситуацию, когда дамп БД все еще записывается, и что-то идет не так во время передачи или восстановления по сети. Затем вам придется перезапустить файл дампа, но вы не можете просто скопировать его через scp потому что MariaDB все еще пишет в него, такая же проблема, как и раньше.

Похоже, что то, чего вы пытаетесь достичь, лучше всего реализовать с помощью нескольких дополнительных инструментов:

экран - чтобы процесс выполнялся, даже если сеанс ssh отключает pxz - для ускорения сжатия за счет использования всех доступных ядер rsync - для возобновления передачи

Три описанных вами шага станут:

ssh -l webuser 10.0.0.99 'screen -d -m "cd /var/www/drupal7/htdocs/site_name && drush sql-dump | nice -n19 pxz -1 > /home/webuser/db_dump.sql.xz"'
rsync -a webuser@10.0.0.99:/home/webuser/db_dump.sql.xz db_dump.sql.xz
xzcat /home/webuser/db_dump.sql.xz | drush sqlc

Процесс дампа будет выполняться в сеансе отсоединенного экрана, поэтому, если сеанс ssh прерывается, он все равно будет продолжаться до завершения.

rsync можно запускать повторно, пока drush sql-dump запущен, и он будет постепенно передавать лишнюю часть файла, которая появилась после последнего rsync.

Вам нужно будет каким-то образом отметить завершение, чтобы вы не выполняли последний шаг до завершения дампа и rsync.

Я надеюсь, что это укажет вам правильное направление для достижения того, что вы пытаетесь сделать.

Это пошаговое руководство, как я это решил:

1.) Старый сервер: я создал такой FIFO (именованный канал)

mkfifo /home/webuser/db_dump.fifo

2.) Новый сервер: я подключился к FIFO на старом сервере через SSH и использовал канал для восстановления

cd /var/www/drupal7/htdocs/site_name
nohup ssh -l webuser 10.0.0.99 "cat < /home/webuser/db_dump.fifo" | xz -d - | drush sqlc &

Обратите внимание, что я использовал nohup так что в случае потери связи с новым сервером передача и восстановление продолжаются. Также обратите внимание, что на этом этапе команда просто ожидает, потому что в FIFO еще не поступили данные.

3.) Старый сервер:

cd /var/www/drupal7/htdocs/site_name
nohup drush sql-dump | xz -1 -" | tee -a /home/webuser/site_name.sql.xz > /home/webuser/db_dump.fifo &

Очередной раз nohup используется, поэтому дамп базы данных продолжается, даже если я потеряю ssh-соединение со старым сервером. После выполнения этой команды автоматически запускается операция передачи и восстановления на новом сервере.

4.) Новый сервер: в случае, если сетевое соединение между старым и новым сервером было прервано или что-то пошло не так во время восстановления на новом сервере, я запустил второй сценарий параллельно для передачи дампа БД на новый сервер, поэтому после переноса я может снова вручную выполнить восстановление.

Вот сценарий:

#!/bin/bash

while [ ! -f ./stop ]; do
  printf "\n\nsyncing\n"

  rsync --append --compress-level=9 -e ssh webuser@10.0.0.99:/home/webuser/site_name.sql.xz .

  sleep 60

done

printf "\n\nsync and check\n"

rsync --append-verify --compress-level=9 -e ssh  webuser@10.0.0.99:/home/webuser/site_name.sql.xz .

После завершения операции дампа БД на старом сервере я сделал touch stop чтобы остановить сценарий. Обратите внимание, что я использую rsync --append внутри цикла и rsync --append-verify в конце. Так как --apend-verify выполняет контрольные суммы по файлу для передачи. Я полагал, что это вызовет дополнительную нагрузку ввода-вывода, и я хотел свести это к минимуму во время дампа и передачи.

Таким образом, с этим методом, когда передача + восстановление через FIFO не удалась, вы потеряете только время на восстановление БД, потому что файл дампа БД передается параллельно.

Самый простой способ синхронизировать базу данных - использовать rsync в самом хранилище данных и игнорируйте архивирование, дамп и т. д. Возьмите начальную rsync перед окном простоя (если хотите, вы можете запускать его несколько раз; каждый раз "дельта" изменений должна уменьшаться, потому что время между запусками сокращается), а затем, когда время простоя начинается, остановите сервер базы данных, выполните последнюю rsync бегите к новой машине, запустите сервер базы данных на новой машине, и все готово.