天天看點

Mixed format + DML limit 引發的血案

mysql版本 5.6.16 db架構(級聯複制) m --> new_m(log_slave_update)--> s 相信做db拆分,機房搬遷,資料庫更新,都會用到這種類似的架構吧。 那麼問題來了,最近做資料校驗的時候,發現new_s 的資料竟然比 m,new_m 還多,是否奇怪?
Mixed format + DML limit 引發的血案
如何做資料校驗? pt-table-checksum ,或自己寫對比程式。 校驗出來後,發現a表在m,s,new_m三個執行個體上 有300條記錄, new_s,bak_etl 卻有500條記錄
Mixed format + DML limit 引發的血案

為什麼new_m的資料比new_s的資料還要少呢???

這種情況下,隻能比對binlog了,但是binlog資料量如此之大,如何查呢?

具體分析下,m,s,new_m的資料是一樣的,說明他們之間的複制同步沒有問題。

new_s和bak_etl 資料是一樣的,說明他們之間執行的binlog也沒問題。

那麼問題就出在m的binlog , new_m的binlog不一緻了。

換句話說就是:一條delete語句,在m上删除了n條,但是在new_m的binlog中隻記錄了delete n-200

進而導緻最後的slave比master要多200條記錄了。

接下來,我們驗證下

Mixed format + DML limit 引發的血案
Mixed format + DML limit 引發的血案

很明顯,new_m 相比 m,少了很多binlog event,有部分binlog(從214568151開始,全部丢失)都沒了。

ok,問題确認了,但是由于sql語句已經被強制轉換成了row模式的關系,sql語句如何定位呢?

還好,這裡有5.6新特性performance schema的幫助,很快定位到了問題sql

performance_schema> select * from events_statements_summary_by_digest where digest_text like '%broker_user_relation_sub%'g

Mixed format + DML limit 引發的血案

到這個地步,有幾個問題:

1) 為什麼binlog會丢失? 2) 什麼情況下會丢失?

這幾個問題,經過反複測試,得出以下結論。

為什麼binlog會丢失?

條件1:當binlog format 設定為mixed時,普通複制不會有問題,但是級聯複制在特殊情況下會binlog丢失。 條件2:當出現大量資料(400w左右)掃描的更新,删除,插入的時候,且有不确定dml語句(如:delete from table where data<'n' limit )的時候. 當條件1 和 條件2 同時滿足時,會導緻問題的發生。以上案例,就是證據。

接下來,我們再來測試下我們的理論。這次我們不用delete + limit,用 insert into select

Mixed format + DML limit 引發的血案
Mixed format + DML limit 引發的血案

強烈建議mysql binlog format 設定成row模式來確定主從資料的一緻性。

set global binlog_format=row; 禁止非确定性因素的dml,尤其是dml + limit 且沒有order by的情況。