从奴隶恢复崩溃的MySQL主服务器

我们正在使用asynchronous复制构build一个简单的主/从MySQLconfiguration,在服务器和基于innoDB的表上都使用MySQL企业版5.5.17。 在主服务器崩溃的情况下,我们希望向用户提供使用从服务器的最新数据库内容恢复主服务器的可能性。 在主服务器上,数据库和二进制日志存储在不同的磁盘设备上,以提高可靠性。

什么是最好的方法来做到这一点? 我试图概述一个这样的程序,但我不确定这是否正确:

  1. 确保从站的中继日志中包含的所有语句都已执行。 理想情况下,我可以执行一个STOP SLAVE IO_THREAD,即使不应该有必要,因为主设备已经崩溃,没有其他语句来到从设备,并等待其余的继电器事件完成。
  2. closures从站上的数据库并将文件复制到数据库文件到主站。
  3. 从relay-log.info和slave上的master.info,我应该能够找出从设备正在从哪个位置读取最新的二进制日志。
  4. 在主服务器崩溃到日志中最后一条语句之前,我可以从主服务器执行的最后一条语句重播主服务器上的二进制日志。
  5. 我应该重置从服务器并在主服务器崩溃之前重新启动从服务器执行的最后一个语句的复制。

这个可以吗?

为了简化对奴隶的晋升,我有一个build议,让奴隶更加接近主人。

你应该使用工具mk-slave-prefetch 。

下面是这个工具的美妙之处:在从属设备上,它将读取中继日志,查找具有WHERE子句的所有查询,将其转换为SELECT并执行它。 这样,InnoDB和MyISAM的caching在主服务器上和在主服务器上基本相同。 差异应该很小。

以下是您将需要的其他东西:使用循环复制来设置主设备和从设备。 这样,主机和从机都启用二进制日志logging。

这有什么帮助? 当主服务器崩溃并且故障切换到从服务器时,主服务器上的文件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) 

请注意两个字段:

  • Relay_Master_Log_File
  • Exec_Master_Log_Pos

这两个字段表示来自在Slave上成功执行的主设备的最后一个日志文件和日志位置。

假设M1崩溃,你故障转移到M2,你提出M1。 您的目标是重新build立循环复制。 随着崩溃,有可能复制失去其地位。 这是做什么:

Step01)在M1上运行SHOW SLAVE STATUS\G

Step02)从Step01获取Relay_Master_Log_File和Exec_Master_Log_Pos。 例如,让Relay_Master_Log_File为mysql-bin.000834, Exec_Master_Log_Pos为823391282。

Step03)运行这些命令

 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

如果你实现循环复制并且使用这些原则正确地编写脚本,你将会实现主从复原。