看mysql手冊中關於 XA 模式下的行爲描述時得知:
master節點執行xa prepare之後如果mysql crash了, 當mysql被恢復時可以通過命令xa recover 找到之前未完成提交的xa 事務,並且通過xa commit進行提交。但是這種情況下,mysql是不會對這個xa事務記錄binlog日誌的。
之前看的時候還不是很明白爲什麼mysql要這麼做,前幾天測試mysql xa 模式下的主從複製時才明白這麼做的原因。
測試中使用sysbench按照預先準備好的lua測試腳本,通過xa進行事務提交,所有的事務都是對測試表進行插入操作。
在sysbench壓測過程中kill -9 master節點,然後停止sysbench腳本並恢復master節點,並xa rollback所有master恢復時通過xa recover能夠查詢到的xa 事務。
最後對比master和slave的數據。
測試過程中master和slave配置了半同步複製,按照我的預期,master和slave的數據應該只會有一條不一致,並且應該是master比slave多1行數據。
但最後的測試結果居然是slave比master多1行。說明有一個xa事務在slave上提交了,而沒有在master上提交。
通過查看並分析發現slave比master多的這行數據在master上進行提交的時候正好碰到了master 被kill -9,導致該xa事務沒有完成,但這個xa事務已經寫完binlog了。。。
這應該就是mysql爲什麼對xa recover出來的xa 事務提交時不記錄binlog的原因,怕重複記錄!
但這就很難保證master和slave的數據一致性了,因爲故障的時候slave得到的binlog上的事務可能在master上還沒提交。
特別是如果主從一致的策略是丟棄master故障時未同步到slave上的事務時,當master恢復的時候應該進行xa commit還是xa rollback需要先去 slave上查看下該xa事務的binlog是否已經同步過來了。
轉載請註明轉自高孝鑫的博客
master節點執行xa prepare之後如果mysql crash了, 當mysql被恢復時可以通過命令xa recover 找到之前未完成提交的xa 事務,並且通過xa commit進行提交。但是這種情況下,mysql是不會對這個xa事務記錄binlog日誌的。
之前看的時候還不是很明白爲什麼mysql要這麼做,前幾天測試mysql xa 模式下的主從複製時才明白這麼做的原因。
測試中使用sysbench按照預先準備好的lua測試腳本,通過xa進行事務提交,所有的事務都是對測試表進行插入操作。
在sysbench壓測過程中kill -9 master節點,然後停止sysbench腳本並恢復master節點,並xa rollback所有master恢復時通過xa recover能夠查詢到的xa 事務。
最後對比master和slave的數據。
測試過程中master和slave配置了半同步複製,按照我的預期,master和slave的數據應該只會有一條不一致,並且應該是master比slave多1行數據。
但最後的測試結果居然是slave比master多1行。說明有一個xa事務在slave上提交了,而沒有在master上提交。
通過查看並分析發現slave比master多的這行數據在master上進行提交的時候正好碰到了master 被kill -9,導致該xa事務沒有完成,但這個xa事務已經寫完binlog了。。。
這應該就是mysql爲什麼對xa recover出來的xa 事務提交時不記錄binlog的原因,怕重複記錄!
但這就很難保證master和slave的數據一致性了,因爲故障的時候slave得到的binlog上的事務可能在master上還沒提交。
特別是如果主從一致的策略是丟棄master故障時未同步到slave上的事務時,當master恢復的時候應該進行xa commit還是xa rollback需要先去 slave上查看下該xa事務的binlog是否已經同步過來了。
轉載請註明轉自高孝鑫的博客