我必须通过 ssh/scp 将带有 43GB MariaDB DB 的 Drupal 站点转移到另一台服务器。
我一大早就有一个有限的停机时间窗口。过去,我通过这样的管道直接传输较小的数据库(<3GB):
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 [email protected]:/home/webuser/db_dump.sql.xz .
xzcat /home/webuser/db_dump.sql.xz | drush sqlc
但是现在这些步骤是连续的,需要更多时间,这意味着在出现问题时重做步骤的时间更少。
所以我想我正在寻找一种在旧服务器上创建数据库转储的方法,并有第二个独立的进程将数据传输到新服务器并开始在新服务器上恢复数据库。
只需使用
scp [email protected]:/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 仍在写入它,所以问题和以前一样。
听起来您想要实现的目标最好使用一些额外的工具来实现:
screen - 即使 ssh 会话断开连接也使进程执行 pxz - 通过使用所有可用内核来加速压缩 rsync - 使传输可恢复
您描述的三个步骤将变为:
转储过程将在分离的屏幕会话中运行,因此如果 ssh 会话中断,它仍将继续进行直到完成。
rsync 可以在运行时重复
drush sql-dump
运行,它将增量传输自上次 rsync 以来出现的文件的额外部分。您将需要以某种方式标记完成,以便在转储和 rsync 完成之前不要执行最后一步。
我希望这能为您指明正确的方向,以实现您正在尝试做的事情。
同步数据库最直接的方法是
rsync
在数据存储本身上使用并忽略所有的压缩包、转储等。在停机时间窗口之前进行初始rsync
设置(如果您愿意,可以多次运行它;每次更改的“增量”应该减少,因为运行之间的时间减少了),然后当停机时间开始时,停止数据库服务器,对新机器进行最后一次rsync
运行,在新机器上启动数据库服务器,就完成了。这是我如何解决它的分步指南:
1.)旧服务器:我创建了一个这样的 FIFO(命名管道)
2.)新服务器:我通过SSH连接到旧服务器上的FIFO并使用管道进行恢复
请注意,我使用
nohup
的是这样,以防万一我失去与新服务器的连接,传输和恢复将继续。另请注意,此时命令只是等待,因为尚未将数据馈入 FIFO。3.) 旧服务器:
再次
nohup
使用,因此即使我失去与旧服务器的 ssh 连接,数据库转储也会继续。执行此命令后,新服务器上的传输和恢复操作将自动启动。4.)新服务器:对于新旧服务器之间的网络连接中断或在新服务器上恢复过程中出现问题的情况,我并行运行了第二个脚本将数据库转储传输到新服务器,所以一旦转移我可以再次手动进行还原。
这是脚本:
一旦旧服务器上的数据库转储操作完成,我就
touch stop
停止了脚本。请注意,我rsync --append
在循环内部和rsync --append-verify
末尾使用。因为--apend-verify
对要传输的文件进行校验和,所以我认为它会导致额外的 IO 负载,我希望在转储和传输期间将其保持在最低限度。总之,使用这种方法,当通过 FIFO 传输+恢复失败时,您只会浪费恢复 DB 的时间,因为 DB 转储文件是并行传输的。