断电后MySQL复制问题

Modified on: Sun, 10 Nov 2019 13:40:02 +0800

在我们的数据中心停电后,奴隶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日志,我们有:

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
  1. Slave状态显示Exec_Master_Log_Pos和Read_Master_Log_Pos都是724207814,然后是二进制日志bin-log.004712。据我所知,这个值是二进制日志文件中的字节位置。
  2. 那个bin-log.004712文件只有724200412字节,所以奴隶认为他们比文件中实际持久存在的工作量多7402个字节(在ext3 fs,RAID-10,RHEL5上) 。因此关于不可能的日志位置的错误消息等
  3. 醇>

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

    我正在考虑的选项:

    1. 将每个从站设置为指向下一个bin-log文件中的位置0(bin-log.004713)并让它们离开,但我不确定它有多安全,或者可能丢失多少数据。 / LI>
    2. 我是否需要进行完整备份和恢复(假设由于InnoDB表上的表锁而导致相关的停机时间)?如果可能的话,我想避免这样做。
    3. 醇>

      更新:

      我错过了另一个选项:将每个从属执行位置稍微指回一点,这样它就会尝试复制已经从bin-log.004712处理过的命令。

作者:,jabley

最佳答案

我选择了第一个选项。

这已经达到奴隶开始尝试进行与主键冲突的插入的程度。如前所述,奴隶做了比主bin-log持续更多的工作。我没想到的一个方面是奴隶包含不在主人中的数据;也就是说,奴隶在停电之前坚持了一些交易,主人HAD NOT持续存在。

因为对于我的情况,这些交易不是与支付相关或类似的,我选择从奴隶中删除数据(从而丢失了一些已发生的数据,但在主人中不存在)然后让复制再次运行。这使奴隶完全更新。如果数据更重要,我们有足够的自动增量补偿,为我们提供了一些手动争用数据的空间,并确保参考完整性不会受到影响。值得庆幸的是,在这种情况下我们不需要这样做。

对于处于这种困境的(被动)主 - 主配置的机器,我选择了类似的方法。通过被动master-master,我的意思是我们有一个主动主服务器(serverA),它是所有写入的地方,并且有一个被动主服务器(serverB),它允许在零停机时间内进行模式更新。主动主服务器(serverA)中的数据被选为真实值,尽管知道这意味着我们丢失了几个不重要的持久交易。

  • 更改了奴隶上的日志文件和位置。

    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
    
  • 删除slave(serverB)上服务器A上主服务器中不存在的行。

    DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB
    SHOW MASTER STATUS\G; -- get the new master log position on serverB
    
  • 移动活动主服务器(serverA)slave exec位置以跳过被动主服务器(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.
    
作者:,community wiki,jabley

相关问答

添加新评论