問題描述
AWS RDS Slave 複製中斷,RDS 控制檯顯示錯誤信息如下:
Apply Error 1399: Error 'XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state' on query. Default database: 'xsy_relation'. Query: 'ROLLBACK'
影響範圍
1.Slave 複製中斷,主從數據不一致.
2.BI 項目無法獲取slave binlog,影響BI 業務正常使用。
3.不定期出現這個問題,每次都需要通過RDS console 重新創建slave(沒有RDS slave stop/start 權限)
問題分析
通過show slave status\G 查看從庫具體的出錯原因,解析出錯點對應的binlog,找到出錯的根源
Master_Log_File: mysql-bin-changelog.094948
Read_Master_Log_Pos: 2129749
Relay_Log_File: relaylog.166532
Relay_Log_Pos: 330
Relay_Master_Log_File: mysql-bin-changelog.094497
Slave_IO_Running: No
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table: mysql.plugin,mysql.rds_monitor,mysql.rds_sysinfo,innodb_memcache.cache_policies,mysql.rds_history,innodb_memcache.config_options,mysql.rds_configuration,mysql.rds_replication_status
Last_Errno: 1399
Last_Error: Error 'XAER_RMFAIL: The command cannot be executed when global transaction is in the ACTIVE state' on query. Default database: 'xsy_relation'. Query: 'ROLLBACK'
Exec_Master_Log_Pos: 154
Relay_Log_Space: 3951373169
Master 上解析binlog
解析Master上的binlog,發現出錯的事件是XA事務中一個DROP TEMPORARY TABLE 的操作回滾了。
而正常情況下 CREATE/ DROP TEMPORARY TABLE的操作是不會不復制到從庫上的。
slave上找不到這個臨時表,所以在slave rollback TEMPORARY TABLE 會導致複製中斷。
什麼情況會出現XA事務中回滾臨時表的操作呢?
- Java 腳本使用了BufferedUpdater
- Java腳本執行失敗
必須滿足以上兩個條件纔會觸發在XA事務中rollback temporary table 的操作。
爲什麼RDS主從複製中斷是不定期的?
- 因爲大多數情況下,JAVA腳本執行都是正常的。
- 測試環境是單Master節點,不會出現主從複製失敗的情況。
解決方案
- JAVA 腳本中不使用BufferedUpdater
- 使用物理臨時表代替TEMPORARY TABLE
使用如下命令可以查看到具體的master上對應的binlog事件。
SHOW BINLOG EVENTS in 'mysql-bin-changelog.09XXX' from 154 ;