Мне нужно перенести сайт 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
бегите к новой машине, запустите сервер базы данных на новой машине, и все готово.