用pt-table-sync修複不一致的資料

來源:互聯網
上載者:User

用pt-table-sync修複不一致的資料

上一篇用pt-table-checksum校正資料一致性介紹了校正主從資料是否一致的方法,當確定主從資料不一致後,就要考慮如何修複。這裡推薦percona-toolkit的另外一個重要工具:pt-table-sync。

percona-toolkit的安裝及簡介 

percona-toolkit 之 【pt-summary】、【pt-mysql-summary】、【pt-config-diff】、【pt-variable-advisor】說明 

pt-table-sync簡介

顧名思義,它用來修複多個執行個體之間資料的不一致。它可以讓主從的資料修複到最終一致,也可以使通過應用雙寫或多寫的多個不相關的資料庫執行個體修複到一致。同時它還內部整合了pt-table-checksum的校正功能,可以一邊校正一邊修複,也可以基於pt-table-checksum的計算結果來進行修複。

工作原理1. 單行資料checksum值的計算

計算邏輯與pt-table-checksum一樣,也是先檢查表結構,並擷取每一列的資料類型,把所有資料類型都轉化為字串,然後用concat_ws()函數進行串連,由此計算出該行的checksum值。checksum預設採用crc32計算。

2. 資料區塊checksum值的計算

同pt-table-checksum工具一樣,pt-table-sync會智能分析表上的索引,然後把表的資料split成若干個chunk,計算的時候以chunk為單位。可以理解為把chunk內所有行的資料拼接起來,再計算crc32的值,即得到該chunk的checksum值。

3. 壞塊檢測和修複

前面兩步,pt-table-sync與pt-table-checksum的演算法和原理一樣。再往下,就開始有所不同:

pt-table-checksum只是校正,所以它把checksum結果儲存到統計表,然後把執行過的sql語句記錄到binlog中,任務就算完成。語句級的複製把計算邏輯傳遞到從庫,並在從庫執行相同的計算。pt-table-checksum的演算法本身並不在意從庫的延遲,延遲多少都一樣計算(有同事對此不理解,可以參考我的前一篇文章),不會影響計算結果的正確性(但是我們還是會檢測延遲,因為延遲太多會影響業務,所以總是要加上—max-lag來限流)。
pt-table-sync則不同。它首先要完成chunk的checksum值的計算,一旦發現主從上同樣的chunk的checksum值不同,就深入到該chunk內部,逐行比較並修複有問題的行。其計算邏輯描述如下(以修複主從結構的資料不一致為例,業務雙寫的情況修複起來更複雜—因為涉及到衝突解決和基準選擇的問題,限於篇幅,這裡不介紹):

  1. 對每一個從庫,每一個表,迴圈進行如下校正和修複過程。
  2. 對每一個chunk,在校正時加上for update鎖。一旦獲得鎖,就記錄下當前主庫的show master status值。
  3. 在從庫上執行select master_pos_wait()函數,等待從庫sql線程執行到show master status得到的位置。以此保證,主從上關於這個chunk的內容均不再改變。
  4. 對這個chunk執行checksum,然後與主庫的checksum進行比較。
  5. 如果checksum相同,說明主從資料一致,就繼續下一個chunk。
  6. 如果checksum不同,說明該chunk有不一致。深入chunk內部,逐行計算checksum並比較(單行的checksum的比較過程與chunk的比較過程一樣,單行實際是chunk的size為1的特例)。
  7. 如果發現某行不一致,則標記下來。繼續檢測剩餘行,直到這個chunk結束。
  8. 對找到的主從不一致的行,採用replace into語句,在主庫執行一遍以產生該行全量的binlog,並同步到從庫,這會以主庫資料為基準來修複從庫;對於主庫有的行而從庫沒有的行,採用replace在主庫上插入(必須不能是insert);對於從庫有而主庫沒有的行,通過在主庫執行delete來刪除(pt-table-sync強烈建議所有的資料修複都只在主庫進行,而不建議直接修改從庫資料;但是也有特例,後面會講到)。
  9. 直到修複該chunk所有不一致的行。繼續檢查和修複下一個chunk。
  10. 直到這個從庫上所有的表修複結束。開始修複下一個從庫。
重要選項安全選項

—[no]check-triggers 檢查是否有觸發器,有則警告
—[no]foreign-key-checks 預設檢查主外鍵約束,有則警告
—[no]unique-checks 檢查是否有唯一索引,無則警告

過濾選項

—ignore-databases
—ignore-engines
—ignore-tables

其他選項

—replicate=s 與pt-table-checksum結合起來,只修複,而不校正。使用pt-table-checksum之前校正的結果
—bidirectional 雙向同步。通常都以主庫的資料為準,如果開啟雙向同步,就要定義衝突解決規則,會比較複雜

用法舉例

假設10.55.55.55是主庫,10.73.73.73是它的從庫,連接埠在3306。
1. 先校正:
PTDEBUG=1 ./pt-table-checksum --user=user --password=pass --host=10.55.55.55 --port=3306 --databases=elink --tables=my_cms_10 --recursion-method=processlist 2. 根據校正結果,只修複10.73.73.73從庫與主庫不一致的地方:
PTDEBUG=1 ./pt-table-sync --execute --replicate percona.checksums --sync-to-master h=10.73.73.73,P=3306,u=user,p=pass 3. 修複後,再重新校正一次。執行第一步的語句即可。
4. 檢查修複結果: 登陸到10.73.73.73,執行如下sql語句返回若為空白,則說明修複成功: select * from percona.checksums where master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)

注意事項
  • 採用replace into來修複主從不一致,必須保證被replace的表上有主鍵或唯一鍵,否則replace into退化成insert into,起不到修複的效果。這種情況下pt-table-sync會採用其他校正和修複演算法,但是效率非常低,例如對所有列的group by然後求count(*)(表一定要有主鍵!)。
  • 主從資料不一致需要通過replace into來修複,該sql語句必須是語句級。pt-table-sync會把它發起的所有sql語句都設定為statement格式,而不管全域的binlog_format值。這在級聯A-B-C結構中,也會遇到pt-table-checksum曾經遇到的問題,引起行格式的中繼庫的從庫卡庫是必然。不過pt-table-sync預設會無限遞迴的對從庫的binlog格式進行檢查並警告:
  • 由於pt-table-sync每次只能修複一個表,所以如果修複的是父表,則可能導致子表資料連帶被修複,這可能會修複一個不一致而引入另一個不一致;如果表上有觸發器,也可能遇到同樣問題。所以在有觸發器和主外鍵約束的情況下要慎用。pt-table-sync工具同樣也不歡迎主從異構的結構。pt-table-sync工具預設會進行先決條件的檢查。
  • pt-table-sync在修複過程中不能容忍從庫延遲,這正好與pt-table-checksum相反。如果從庫延遲太多,pt-table-sync會長期持有對chunk的for update鎖,然後等待從庫的master_pos_wait執行完畢或逾時。從庫延遲越大,等待過程就越長,主庫加鎖的時間就越長,對線上影響就越大。因此要嚴格設定max-lag。
  • 對從庫資料的修複通常是在主庫執行sql來同步到從庫。因此,在有多個從庫時,修複某個從庫的資料實際會把修複語句同步到所有從庫。資料修複的代價取決於從庫與主庫不一致的程度,如果某從庫資料與主庫非常不一致,舉例說,這個從庫只有表結構,那麼需要把主庫的所有資料重新灌一遍,然後通過binlog同步,同時會傳遞到所有從庫。這會給線上帶來很大壓力,甚至拖垮叢集。正確的做法是,先用pt-table-checksum校正一遍,確定不一致的程度:如果不同步的很少,用pt-table-sync直接修複;否則,用備份先替換它,然後用pt-table-sync修複。 說明: 這實際提供了一種對myisam備份的思路:如果僅有一個myisam的主庫,要為其增加從庫,則可以:先mysqldump出表結構到從庫上,然後啟動同步,然後用pt-table-sync來修複資料。
總結

pt-table-sync工具很複雜也很強大。它修改資料庫的內容,所以可能造成安全事故。為了安全,建議:使用pt-table-checksum定期檢測資料的一致性,並手動重建損壞較為嚴重的從庫,最後才用pt-table-sync修複剩下的從庫。

本文永久更新連結地址:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.