我们正在使用异步复制构建一个简单的主/从 MySQL 配置,两台服务器上都使用 MySQL enterprise 5.5.17 和基于 innoDB 的表。如果主服务器崩溃,我们希望为用户提供使用从服务器最新的数据库内容恢复主服务器的可能性。在主服务器上,数据库和二进制日志存储在不同的磁盘设备中,以提高可靠性。
最好的方法是什么?我试图概述一个程序,但我不确定这是否正确:
- 确保执行了从服务器的中继日志中包含的所有语句。理想情况下,我可以执行 STOP SLAVE IO_THREAD,即使由于主服务器可能已崩溃且没有其他语句传到从服务器而没有必要,然后等待剩余的中继事件完成。
- 关闭从属服务器上的数据库并将文件复制到主服务器上的数据库文件。
- 从从服务器上的relay-log.info和master.info中,我应该能够找出从服务器上读取的最新二进制日志以及在哪个位置。
- 我可以在主服务器上重放二进制日志,从主服务器崩溃前从服务器执行的最后一条语句到日志中可用的最后一条语句。
- 我应该重置 SLAVE 并从主服务器崩溃前从服务器执行的最后一条语句重新启动复制。
这个可以吗?
答案1
为了简化从属设备到主设备的提升,我建议让从属设备与主设备保持更紧密的同步。
你应该使用这个工具mk-从属-预取。
此工具的优点在于:在从服务器上,它将读取中继日志,查找所有包含 WHERE 子句的查询,将其转换为 SELECT 并执行。这样,从服务器上的 InnoDB 和 MyISAM 缓存与主服务器上的缓存基本相同。差异应该很小。
您还需要做以下事情:使用循环复制设置主服务器和从服务器。这样,主服务器和从服务器都启用了二进制日志记录。
这有什么帮助?当主服务器崩溃并且您故障转移到从服务器时,主服务器上的 master.info 文件将包含从服务器执行其 SQL 的最后一个位置。您可以按照以下方法查找:
在此示例中,我们将在 M1 和 M2 之间进行循环复制
在 M2 (您当前的主服务器) 上运行此命令:SHOW SLAVE STATUS\G
你应该看到类似这样的内容:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.64.100.253
Master_User: replicant
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000834
Read_Master_Log_Pos: 823413571
Relay_Log_File: relay-bin.002505
Relay_Log_Pos: 823391419
Relay_Master_Log_File: mysql-bin.000834
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 823391282
Relay_Log_Space: 823413708
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 1
1 row in set (0.00 sec)
请注意两个字段:
- 中继主站日志文件
- 执行主程序日志位置
这两个字段代表在从服务器上成功执行的主机的最后一个日志文件和日志位置。
假设 M1 崩溃,您故障转移到 M2,然后启动 M1。您的目标是重新建立循环复制。崩溃时,复制可能会丢失其位置。以下是要执行的操作:
Step01)SHOW SLAVE STATUS\G
在 M1 上运行
Step02)从 Step01获取Relay_Master_Log_File
和。在此示例中,设为mysql-bin.000834 和823391282。Exec_Master_Log_Pos
Relay_Master_Log_File
Exec_Master_Log_Pos
步骤03)运行这些命令
STOP SLAVE;
CHANGE MASTER TO master_log_file='mysql-bin.000834',master_log_pos=823391282;
START SLAVE;
SELECT SLEEP(5);
SHOW SLAVE STATUS\G
以下是需要寻找的内容:
- 如果 Seconds_Behind_Master 为数字,则表示复制正在运行。只需等到它达到零即可。
- 如果 Seconds_Behind_Master 为 NULL,则复制中断
- 如果 Slave_IO_Running=Yes 且 Slave_SQL_Running=No,则 SQL 错误中断了复制。继续修复错误
- 如果 Slave_IO_Running=No 且 Slave_SQL_Running=Yes,则日志文件或日志位置不存在。
你可以用以下方法修复
STOP SLAVE;
CHANGE MASTER TO master_log_file='mysql-bin.000835',master_log_pos=<new pos>;
START SLAVE;
SELECT SLEEP(5);
SHOW SLAVE STATUS\G
newpos 是什么?
- 对于 MySQL 5.5,newpos 为 107
- 对于 MySQL 5.1,newpos 为 106
- 对于 MySQL 5.0,newpos 为 98
如果您实现循环复制并使用这些原则正确地编写脚本,您将实现主服务器和从服务器的恢复。