用pt-table-checksum校正資料一致性
主從資料的一致性校正是個頭疼的問題,偶爾被業務投訴主從資料不一致,或者幾個從庫之間的資料不一致,這會令人沮喪。通常我們僅有一種辦法,熱備主庫,然後替換掉所有的從庫。這不僅代價非常大,而且類似治標不治本的方案,讓人十分不安。因此我們需要合適的工具,至少幫我們回答下面三個問題:
- 是從庫延遲導致了使用者看到的資料不一致,還是真的主從資料就不一致?
- 如果不一致,這個比例究竟多大?
- 下次還會出現嗎?
回答清楚這幾個問題,有助於我們決定是否修複,以及修複的方式,還可以幫我們找出不一致的資料,進而定位問題根源。而percona的pt-table-checksum正是我們想要的。
pt-table-checksum簡介
pt-table-checksum是著名的percona-toolkit工具集的工具之一。它通過在主庫執行基於statement的sql語句來產生主庫資料區塊的checksum,把相同的sql語句傳遞到從庫,並在從庫上計算相同資料區塊的checksum,最後,比較主從庫上相同資料區塊的checksum值,由此判斷主從資料是否一致。這種校正是分表進行的,在每個表內部又是分塊進行的,而且pt工具本身提供了非常多的限流選項,因此對線上服務的衝擊較小。
percona-toolkit的安裝及簡介
percona-toolkit 之 【pt-summary】、【pt-mysql-summary】、【pt-config-diff】、【pt-variable-advisor】說明
checksum計算原理1. 單行資料checksum值的計算
pt工具先檢查表的結構,並擷取每一列的資料類型,把所有資料類型都轉化為字串,然後用concat_ws()函數進行串連,由此計算出該行的checksum值。checksum預設採用crc32,你可以自己定義效率更高的udf。
2. 資料區塊checksum值的計算
如果一行一行的計算checksum再去和從庫比較,那麼效率會非常低下。pt工具選擇智能分析表上的索引,然後把表的資料split成一個個chunk,計算的時候也是以chunk為單位。因此引入了彙總函式BIT_XOR()。它的功能可以理解為把這個chunk內的所有行的資料拼接起來,再計算crc32的值,就得到這個chunk的checksum值。sql語句如下:
這其中還有count(*),用來計算chunk包含的行數。每一次對chunk進行checksum後,pt工具都會對耗時進行統計分析,並智能調整下一個chunk的大小,避免chunk太大對線上造成影響,同時也要避免chunk太小而效率低下。
3. 一致性如何保證
當pt工具在計算主庫上某chunk的checksum時,主庫可能還在更新,同時從庫可能延遲使得relay-log中還有與這個chunk資料相關的更新,那該怎麼保證主庫與從庫計算的是”同一份”資料?答案是加for update當前讀鎖,這保證了主庫的某個chunk內部資料的一致性。否則,1000個人chekcusm同樣的1000行資料,可能得到1000個不同的結果,你無法避開mvcc的幹擾!獲得for update鎖後,pt工具開始計算chunk的checksum值,並把計算結果儲存到pt工具自建的結果表中(採用replace into select的方式),然後釋放鎖。該語句最終會傳遞到從庫並執行相同的計算邏輯。
更多詳情見請繼續閱讀下一頁的精彩內容: