导入转储文件,不会中断服务

时间:2012-11-30 16:56:21

标签: mysql mysqldump database-backups

我开发了一种用于实时mySQL数据库同步的自定义机制,与内置的mySQL主/从复制相比,它提供了更高的可靠性(数据完整性)。

同步机制以每5秒常规触发的周期性循环运行,由以下阶段构成:

  1. master 数据库被命令通过mysqldump生成转储文件
  2. 转储文件传输到远程服务器,拥有从属数据库。此转移利用rsync的增量算法和数据压缩
  3. 远程服务器等待接收确认以继续
  4. 远程服务器将收到的转储文件导入到从属mySQL数据库
  5. 远程服务器向本地服务器确认同步周期已完成
  6. 为了防止主服务器和从服务器之间出现任何不一致,转储文件会删除整个从属数据库,并使用mysqldump调用--add-drop-database

    由于slave在不中断mySQL守护进程的情况下导入转储文件,我担心在mySQL读取转储文件中的drop database指令之后的时间窗口期间,以及在mySQL完成所有表的重新创建之前,一个试图访问数据库以获取尚未重新创建的表的mySQL客户端可能会使他的请求失败。

    可能发生这种情况,或者在娱乐期间,任何试图访问数据库的最终客户端都会被静静地暂停,直到其请求被执行为止?最终,可以应用哪些解决方案?

1 个答案:

答案 0 :(得分:3)

为了避免从可能尝试连接到特定数据库的任何客户端下拉出地毯,最好的方法可能是每次刷新时不DROPCREATE数据库。

可能证明更可靠的方法是一次一个地将数据加载到备用表中,然后进行批量切换。例如:

CREATE TABLE __users (...);
INSERT INTO __users (...) VALUES (...), ...;

CREATE TABLE __things (...);
INSERT INTO __things (...) VALUES (...), ...;

RENAME users to _users, __users to users, things to _things, __things to things;
DROP table _users;
DROP table _things;

如果你把所有内容都正确排列,那么大规模重命名操作将以原子方式执行。

您必须更改原始SQL转储本身中的名称,或转储为更易于解析的格式,例如SELECT INTO ... OUTFILE以及稍后使用LOAD DATA INFILE进行恢复。

请注意,此方法不会处理VIEWTRIGGER个对象。它只适用于普通的旧表。在重新加载过程中,您还需要有足够的可用空间来创建整个数据库的两个副本。