顧名思義,它用來修復多個實例之間數據的不一致。它可讓主從的數據修復到最終一致,也可使經過應用雙寫或多寫的多個不相關的數據庫實例修復到一致。同時它還內部集成了pt-table-checksum的校驗功能,能夠一邊校驗一邊修復,也能夠基於pt-table-checksum的計算結果來進行修復。html
工做原理
1. 單行數據checksum值的計算
計算邏輯與pt-table-checksum同樣,也是先檢查表結構,並獲取每一列的數據類型,把全部數據類型都轉化爲字符串,而後用concat_ws()函數進行鏈接,由此計算出該行的checksum值。checksum默認採用crc32計算。mysql
2. 數據塊checksum值的計算
同pt-table-checksum工具同樣,pt-table-sync會智能分析表上的索引,而後把表的數據split成若干個chunk,計算的時候以chunk爲單位。能夠理解爲把chunk內全部行的數據拼接起來,再計算crc32的值,即獲得該chunk的checksum值。算法
3. 壞塊檢測和修復
前面兩步,pt-table-sync與pt-table-checksum的算法和原理同樣。再往下,就開始有所不一樣:sql
pt-table-checksum只是校驗,因此它把checksum結果存儲到統計表,而後把執行過的sql語句記錄到binlog中,任務就算完成。語句級的複製把計算邏輯傳遞到從庫,並在從庫執行相同的計算。pt-table-checksum的算法自己並不在乎從庫的延遲,延遲多少都同樣計算(有同事對此不理解,能夠參考個人前一篇文章),不會影響計算結果的正確性(可是咱們仍是會檢測延遲,由於延遲太多會影響業務,因此老是要加上—max-lag來限流)。
pt-table-sync則不一樣。它首先要完成chunk的checksum值的計算,一旦發現主從上一樣的chunk的checksum值不一樣,就深刻到該chunk內部,逐行比較並修復有問題的行。其計算邏輯描述以下(以修復主從結構的數據不一致爲例,業務雙寫的狀況修復起來更復雜—由於涉及到衝突解決和基準選擇的問題,限於篇幅,這裏不介紹):數據庫
- 對每個從庫,每個表,循環進行以下校驗和修復過程。
- 對每個chunk,在校驗時加上for update鎖。一旦得到鎖,就記錄下當前主庫的show master status值。
- 在從庫上執行select master_pos_wait()函數,等待從庫sql線程執行到show master status獲得的位置。以此保證,主從上關於這個chunk的內容均再也不改變。
- 對這個chunk執行checksum,而後與主庫的checksum進行比較。
- 若是checksum相同,說明主從數據一致,就繼續下一個chunk。
- 若是checksum不一樣,說明該chunk有不一致。深刻chunk內部,逐行計算checksum並比較(單行的checksum的比較過程與chunk的比較過程同樣,單行實際是chunk的size爲1的特例)。
- 若是發現某行不一致,則標記下來。繼續檢測剩餘行,直到這個chunk結束。
- 對找到的主從不一致的行,採用replace into語句,在主庫執行一遍以生成該行全量的binlog,並同步到從庫,這會以主庫數據爲基準來修復從庫;對於主庫有的行而從庫沒有的行,採用replace在主庫上插入(必須不能是insert);對於從庫有而主庫沒有的行,經過在主庫執行delete來刪除(pt-table-sync強烈建議全部的數據修復都只在主庫進行,而不建議直接修改從庫數據;可是也有特例,後面會講到)。
- 直到修復該chunk全部不一致的行。繼續檢查和修復下一個chunk。
- 直到這個從庫上全部的表修復結束。開始修復下一個從庫。
重要選項
安全選項
—[no]check-triggers 檢查是否有觸發器,有則警告
—[no]foreign-key-checks 默認檢查主外鍵約束,有則警告
—[no]unique-checks 檢查是否有惟一索引,無則警告
—print 顯示同步須要執行的語句安全
過濾選項
—ignore-databases
—ignore-engines
—ignore-tablesapp
其餘選項
—replicate=s 與pt-table-checksum結合起來,只修復,而不校驗。使用pt-table-checksum以前校驗的結果
—bidirectional 雙向同步。一般都以主庫的數據爲準,若是開啓雙向同步,就要定義衝突解決規則,會比較複雜
—execute 執行數據同步
—charset=utf8 設置字符集函數
用法舉例
假設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)
master:10.0.0.96
slave:10.0.0.30
主從數據同步(同步主庫的數據到從庫)
1.同步單個數據庫
./pt-table-sync --execute --sync-to-master --charset=utf8 --user=root --password=qazwsx$%^456 h=10.0.0.30 --database=common --port=3306
2.根據pt-table-checksum的結果同步主庫數據到從庫
./pt-table-sync --execute --charset=utf8 --replicate common.checksums --user=root --password=qazwsx$%^456 h=10.0.0.96 --database=common --port=3306
3.同步某個數據庫的指定表(單表或者多表)
./pt-table-sync --execute --sync-to-master --charset=utf8 --user=root --password=qazwsx$%^456 h=10.0.0.30 --database=common --tables=tmp_order --port=3306
./pt-table-sync --execute --sync-to-master --charset=utf8 --user=root --password=qazwsx$%^456 h=10.0.0.30 --database=common --tables=tmp_order,system_shipping_method --port=3306
4.同步多個數據庫
./pt-table-sync --execute --sync-to-master --charset=utf8 --user=root --password=qazwsx$%^456 h=10.0.0.30 --database=common,db1 --port=3306工具
注意事項
- 採用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修復剩下的從庫。this
文章轉載鏈接http://nettedfish.sinaapp.com/blog/2013/06/05/synchronizes-data-efficiently-by-pt-table-sync/
英文參考鏈接http://www.percona.com/doc/percona-toolkit/2.2/pt-table-sync.html