天天看點

MySQL如何對主從資料不一緻的情況進行校驗并繼續同步

兩台mysql,發生了種種種種,導緻了兩個表的資料不一緻,但是同步還在正常進行,後來意識到這種問題(可能之前skip啊,或者一開始搭建的時候就是不一緻的狀态),該如何修複呢?

我們看可以來看下percona-toolkit這個工具是如何修複這種情況的

校驗:

主庫:192.168.100.8 3306

從庫:192.168.100.12 3305

mysql version:mysql-5.6.30

1.master 伺服器安裝yum依賴包

2.安裝percona-toolkit工具包

3.master與slave資料庫建立以及使用者授權

4.進行校驗 master上執行

#-h -u -p -p -s -d 連接配接資訊 

#--nocheck-replication-filters 檢測中忽略mysql 配置參數binlog_ignore_db等。

#--nocheck-binlog-format 不檢測日志格式 

#--replicate 指定checksum 存儲的db和表, 如pt.checksum 

# --chunk-size, --chunk-size-limit 用于指定檢測塊的大小。 可控性更強 

# --ignore-databases/tables/column 跳出指定元素的過濾 

# --lock-wait-timeout innodb 鎖的逾時設定, 預設為1 

# --max-load 設定最大并發連接配接數 

# --replicate-check-only 隻輸出資料不一緻的資訊。 

# --help 

校驗結果

ts :完成檢查的時間。 

errors :檢查時候發生錯誤和警告的數量。 

diffs :0表示一緻,1表示不一緻。當指定--no-replicate-check時,會一直為0,當指定--replicate-check-only會顯示不同的資訊。

rows :表的行數。 

chunks :被劃分到表中的塊的數目。 

skipped :由于錯誤或警告或過大,則跳過塊的數目。 

time :執行的時間。 

table :被檢查的表名。 

注意:

要是在執行指令的過程遇到找不到從伺服器的錯誤: 

預設是通過show processlist 找到host的值或show slave hosts 找到host的值。

關于--recursion-method參數的設定有:

在從庫的配置檔案裡加: 

report_host = 192.168.200.25 #設定成本地位址

最後再執行以上指令(多加--recursion-method=hosts 參數): 

先校驗出哪些庫的表不同步,然後指定庫與表生成語句,采用第二種方法, 将生成的sql語句在從庫執行即可。

5.資料同步,複制,消除差異(master伺服器運作) 要是有中文的則需要加上:--charset=utf8,防止亂碼。

i.自動消除差異(不推薦) 

ii.列印出sql語句,人工幹預到slave庫執行(推薦) 

#--sync-to-master :指定一個dsn,即從的ip,他會通過show processlist或show slave status 去自動的找主。

#--replicate :指定通過pt-table-checksum得到的表,這2個工具差不多都會一直用。 

#--print :列印,但不執行指令。 

#--execute :執行指令。

7.實際解決:

由于其中一個表的資料較大,采用dump導出的方式在從庫上恢複

1.第一個執行采用pt-table-sync方式恢複

2.第二個表采用導出導入的方式恢複

同步完成後再校驗:

注意事項

1.采用replace into來修複主從不一緻,必須保證被replace的表上有主鍵或唯一鍵,否則replace into退化成insert into,起不到修複的效果。這種情況下pt-table-sync會采用其他校驗和修複算法,但是效率非常低,例如對所有列的group by然後求count(*)(表一定要有主鍵!)。

2.主從資料不一緻需要通過replace into來修複,該sql語句必須是語句級。pt-table-sync會把它發起的所有sql語句都設定為statement格式,而不管全局的binlog_format值。這在級聯a-b-c結構中,也會遇到pt-table-checksum曾經遇到的問題,引起行格式的中繼庫的從庫卡庫是必然。不過pt-table-sync預設會無限遞歸的對從庫的binlog格式進行檢查并警告。

3.由于pt-table-sync每次隻能修複一個表,是以如果修複的是父表,則可能導緻子表資料連帶被修複,這可能會修複一個不一緻而引入另一個不一緻;如果表上有觸發器,也可能遇到同樣問題。是以在有觸發器和主外鍵限制的情況下要慎用。pt-table-sync工具同樣也不歡迎主從異構的結構。pt-table-sync工具預設會進行先決條件的檢查。

4.pt-table-sync在修複過程中不能容忍從庫延遲,這正好與pt-table-checksum相反。如果從庫延遲太多,pt-table-sync會長期持有對chunk的for update鎖,然後等待從庫的master_pos_wait執行完畢或逾時。從庫延遲越大,等待過程就越長,主庫加鎖的時間就越長,對線上影響就越大。是以要嚴格設定max-lag。

5.對從庫資料的修複通常是在主庫執行sql來同步到從庫。是以,在有多個從庫時,修複某個從庫的資料實際會把修複語句同步到所有從庫。資料修複的代價取決于從庫與主庫不一緻的程度,如果某從庫資料與主庫非常不一緻,舉例說,這個從庫隻有表結構,那麼需要把主庫的所有資料重新灌一遍,然後通過binlog同步,同時會傳遞到所有從庫。這會給線上帶來很大壓力,甚至拖垮叢集。正确的做法是,先用pt-table-checksum校驗一遍,确定不一緻的程度:如果不同步的很少,用pt-table-sync直接修複;否則,用備份先替換它,然後用pt-table-sync修複。 說明: 這實際提供了一種對myisam備份的思路:如果僅有一個myisam的主庫,要為其增加從庫,則可以:先mysqldump出表結構到從庫上,然後啟動同步,然後用pt-table-sync來修複資料。