如何有效地转储巨大的MySQL innodb数据库?


8

我有一个Ubuntu 10.04生产型MySQL数据库服务器,其中数据库的总大小为260 GB,而根分区的大小本身为300 GB,用于存储数据库,这实际上意味着大约96%的/已满,并且没有空间来存储转储/备份等等。到目前为止,没有其他磁盘连接到服务器。

我的任务是将该数据库迁移到位于不同数据中心的其他服务器。问题是如何在最少的停机时间内有效地做到这一点?

我在考虑以下方面:

  • 请求将额外的驱动器连接到服务器,并在该驱动器中进行转储。[编辑:现在不可能。]
  • 将转储转移到新服务器,还原它,并使新服务器成为现有服务器的从属服务器,以保持数据同步
  • 当需要迁移时,中断复制,更新从属配置以接受读/写请求,并使旧服务器为只读,这样它就不会招待任何写请求,并告诉应用程序开发人员使用新的db IP地址更新该配置。

您对改进此任务或任何其他更好的方法有何建议?

Answers:


9

如果你正在考虑迁移到另一个数据库服务器使用完全相同的MySQL版本,你可能希望rsyncdatadir从旧服务器到新的服务器。

无论InnoDB文件的布局,甚至MyISAM表的存在,它都将起作用。

  1. 在ServerA上安装与ServerA相同版本的mysql
  2. 在ServerA上,运行RESET MASTER;以清除rsycn进程之前的所有二进制日志。如果未启用二进制日志记录,则可以跳过此步骤。
  3. 在ServerA上,SET GLOBAL innodb_max_dirty_pages_pct = 0;从mysql 运行大约10分钟(这将从InnoDB缓冲池中清除脏页。它还有助于更快地关闭mysql)如果您的数据库全部是MyISAM,则可以跳过此步骤。
  4. 将ServerA的/ var / lib / mysql同步到ServerB上的/ var / lib / mysql
  5. 重复步骤3,直到rsync少于1分钟
  6. service mysql stop 在ServerA上
  7. 再执行一次rsync
  8. scp ServerA:/etc/my.cnf到ServerB:/ etc /。
  9. service mysql start 在ServerB上
  10. service mysql start 在ServerA上(可选)

本质上,这就是这样的脚本会想要的

mysql -u... -p... -e"RESET MASTER;"
mysql -u... -p... -e"SET GLOBAL innodb_max_dirty_pages_pct = 0;"
RSYNCSTOTRY=10
cd /var/lib/mysql
X=0
while [ ${X} -lt ${RSYNCSTOTRY} ]
do
    X=`echo ${X}+1|bc`
    rsync -r * targetserver:/var/lib/mysql/.
    sleep 60
done
service mysql stop
rsync -r * targetserver:/var/lib/mysql/.
service mysql start

DBA FLUSH TABLES WITH READ LOCK;StackExchange的一位同事说,我应该远离基于mysqlperformanceblog.com中的内容

我通读并了解到,对InnoDB表的SELECT FLUSH TABLES WITH READ LOCK;仍然可以允许以某种方式发生写操作。正如Arlukin的评论中指出的那样,LVM可以FLUSH TABLES WITH READ LOCK在InnoDB上正常工作(他的评论为+1)。

对于所有非LVM用户,您都可以使用全MyISAM数据库与一起使用FLUSH TABLES WITH READ LOCK;。对于InnoDB,请坚持--single-tranaction使用mysqldumps。


2
当我们需要手动同步主从设置时,就是这样做的。真的很好。但是在最新的服务器上,我们使用的是LVM快照,因此我们不需要停止服务器。在执行LVM快照之前,我们执行“带读锁的刷新表”,因此可以复制文件。如果要出于备份目的复制所有文件,lvm快照也非常好。因此,请使用LVM设置新服务器,并添加一些额外的空间以执行快照。
阿鲁金

感谢您的详细回答。如果MySQL版本不同怎么办?较旧的版本是5.1,带有ubuntu 10.04,而较新的版本,我愿意使用12.04和默认的5.5。在这种情况下,您建议采用哪种方法?现在也不再需要附加驱动器,因此无论是通过转储/ rsync还是任何其他方式都需要远程发送数据。
加格比尔(Jagbir)2012年

1

如此大小的数据库转储和还原将花费数小时。我会,取决于mysql的版本,只要版本号增加并且主版本号没有跳转。您应该能够将原始数据库文件放在/ var / lib / mysql中,并将它们放在新服务器上,设置权限并使用--skip-grant-tables开关启动服务器。为反映新IP地址的用户添加必要的授权,然后正常重启。

我会解决您的数据库的规模,因为它太大而无法提高效率。


有4个数据库,其大小约为50-90 GB,使整体大小为260 GB。它可能效率不高,但从现在起我必须忍受它。另外,MySQL版本也有所不同,在这种情况下,您的建议是什么?
加格比尔2012年

如果mysql版本不同,请先进行空运行并彻底测试,只要新服务器上的版本号高于旧服务器上的版本号,您就可以了。如果不成功,则可能会使用mysqldump && restore卡住。
詹姆斯·

1

您可以按照以下步骤迁移这个庞大的InnoDB数据库。

  • 安装SSHFS并将远程服务器的相关分区安装在生产服务器上
  • 使用Percona XtraBackup获取InnoDB数据库的热拷贝并将其直接保存到SSHFS安装目录中
  • 此任务将花费几个小时。为了最大程度地减少热拷贝脚本对实时服务器的影响,请使用renice对其设置较低的优先级

    $ renice -n 5 -p <SCRIPT-PID>

  • 确保两个服务器都运行相同版本的MySQL服务器。
  • 一旦完成热拷贝,您可以在新服务器中将其还原,开始复制过程

在此过程中,您可能会感觉很慢,但绝对不会出现停机。与mysqldump相比,Percona XtraBackup将创建一个热副本,该热副本更快且资源消耗更少。这对于庞大的InnoDB数据库是理想的。

根据使用模式和统计信息,当服务器上的流量最小时,可以运行此过程。也许在周末这样做是个好主意?以上只是该过程的概述。您可能需要阅读Percona XtraBackup和SSHFS文档。


1

您可以直接将数据库转储到远程服务器...

$ mysqldump | ssh user@server 'cat - > dumpfile.sql.gz'

... SQL应该很好地压缩,因此您应该使用以下选项之一更快地完成此操作,尽管它也将取决于包装盒中的RAM数量...

$ mysqldump | ssh -C user@server 'cat - > dumpfile.sql.gz'
$ mysqldump | gzip -c | ssh user@server 'cat - > dumpfile.sql.gz'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.