停电后MySQL复制问题

在我们的数据中心停电后,从属MySQL数据库正在苦苦挣扎。

这是在一个奴隶的日志中:

100118 10:05:56 [Note] Slave I/O thread: connected to master 'repl@db1:3306', replication started in log 'bin-log.004712' at position 724207814 100118 10:05:56 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236) 100118 10:05:56 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log 100118 10:05:56 [Note] Slave I/O thread exiting, read up to log 'bin-log.004712', position 724207814 

而控制台显示了更多的细节:

 mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Master_Host: db1 Master_User: repl Master_Port: 3306 Connect_Retry: 10 Master_Log_File: bin-log.004712 Read_Master_Log_Pos: 724207814 Relay_Log_File: mysqld-relay-bin.000105 Relay_Log_Pos: 98 Relay_Master_Log_File: bin-log.004712 Slave_IO_Running: No Slave_SQL_Running: Yes Replicate_Do_DB: mmplive1,mmpjcr,fui 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: 724207814 Relay_Log_Space: 98 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: NULL 1 row in set (0.00 sec) ERROR: No query specified 

看着主人的bin日志,我们有:

 -rw-rw---- 1 mysql mysql 724200412 Jan 18 09:22 bin-log.004712 -rw-rw---- 1 mysql mysql 1904 Jan 18 09:27 bin-log.index -rw-rw---- 1 mysql mysql 5046830 Jan 18 11:22 slow-log -rw-rw---- 1 mysql mysql 198249613 Jan 18 11:24 bin-log.004713 
  1. 从属状态显示Exec_Master_Log_Pos和Read_Master_Log_Pos都是724207814,然后是二进制日志bin-log.004712。 我的理解是这个值是二进制日志文件中的字节位置。
  2. 那个bin-log.004712文件只有724200412个字节,所以从服务器认为他们已经完成了7402个字节的工作,而不是实际上保存在文件中(在ext3 fs,RAID-10,RHEL5上)。 因此,关于不可能的日志位置的错误消息等

什么是修复奴隶的最好方法?

我正在考虑的选项:

  1. 将每个从设备指向下一个bin-log文件(bin-log.004713)中的位置0并让它们离开,但是我不确定它有多安全,或者有多less数据可能会丢失。
  2. 我是否需要做一个完整的备份和恢复(由于InnoDB表上的表锁被认为是相关的停机时间)? 如果可能,我想避免这种情况。

更新:

我错过了另外一个select:将每个从机执行的位置指向一点点,这样就可以尝试复制已经从bin-log.004712处理过的命令。

我去了第一个select。

这种情况发生在从机开始尝试插入与主键冲突的地方。 正如前面提到的那样,奴隶做了比bin-log主人更多的工作。 我没有预料到的一个方面是,奴隶所包含的数据不在主人手中; 即从站在主站HAD不存在的停电之前保持一些事务。

由于我的情况,这些交易是不是付款相关的或类似的,我select从奴隶删除数据(从而失去了一些已发生的数据,但没有在主人存在),然后让复制再次运行。 这使得奴隶完全是最新的。 如果数据更重要,我们有自动递增的偏移量足以给我们一些手动添加数据的空间,并确保参照完整性不受影响。 谢天谢地,在这种情况下我们不需要这样做。

对于处于这种困境的(被动)主站 – 主站configuration的机器,我select了一种类似的方法。 通过被动的主 – 主,我的意思是我们有一个活跃的主(serverA),这是所有写入的地方,以及一个被动的主(serverB),允许模式更新发生在零停机时间。 活动主服务器(serverA)中的数据被选为真实值,尽pipe知道这意味着我们失去了一些不被视为重要的持续事务。

  • 更改了从站上的日志文件和位置。

     CHANGE MASTER MASTER_LOG_FILE='bin-log.004713', MASTER_LOG_POS=0; -- on serverB 
  • 在被动主服务器(serverB)上重新启动从属复制,直到失败,主密钥约束违反,如同其他从属。

      START SLAVE; -- on serverB 
  • 停止从被动主机(serverB)到主动主机(serverA)的从机复制。

     STOP SLAVE; -- on serverA 
  • 删除serverA上主服务器上不存在的从服务器(serverB)上的行。

     DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB SHOW MASTER STATUS\G; -- get the new master log position on serverB 
  • 移动活动的主服务器(serverA)从服务器执行位置以跳过从被动主服务器(serverB)的这些删除操作。

     CHANGE MASTER TO MASTER_LOG_POS=???; --on serverA; use the value just obtained from serverB 
  • 在活动主服务器(serverA)和被动主服务器上重新启动复制。

     START SLAVE; -- on both machines. serverA does nothing and serverB starts catching up. 

这将取决于奴隶是否是主人的精确复制品。 你是第一个select会在一定程度上工作,但奴隶可能会错过主人的信息。 如果你能忍受这一点,因为数据是暂时的或什么的,那就去做吧。 如果重要的是奴隶是适当的复制品,那么第二个select可能是你唯一的select。 不幸的是,MySQL复制并没有带来任何意想不到的干扰,我发现这些问题是更频繁的方式,我想在我的复制架构。