我上一次遇到MySQL主從服務器數據一致性問題,想一想是幾年前的事情了,還依稀記得當時惶恐不安的情景,好在最後藉助Maatkit解決了問題。 幾年後,當我再次面對一樣的問題時,Maatkit已經不復存在,轉而成爲了Percona Toolkit的一部分,不變的是我依舊手忙腳亂,因此仍是記錄一下吧,保不許啥時候又會遇到這個問題。mysql
若是你在MySQL從服務器上遇到相似下面的錯誤信息,那麼恭喜你中招了:sql
mysql> SHOW SLAVE STATUS\G Last_Error: Error 'Duplicate entry '...' for key ...' on query.
爲啥會出現惟一索引鍵值重複?最大的多是錯誤的對從服務器作了寫操做!出現此類錯誤的時候,不少人會用sql_slave_skip_counter操做跳過錯誤,甚至有人寫了腳本,若是有多個錯誤,就循環屢次執行sql_slave_skip_counter:shell
mysql> SET GLOBAL sql_slave_skip_counter = 1; mysql> START SLAVE;
惋惜,即使sql_slave_skip_counter操做可以暫時讓主從恢復工做,但多半數據一致性已經被破壞的更嚴重了,遲早有一天被掩蓋的問題會再次爆發出來。安全
Percona Toolkit裏的pt-table-checksum和pt-table-sync能夠搞定此類問題。它們的安裝很簡單,能夠依照本身的操做系統選擇下 載rpm或者deb軟件包來安裝,固然也可使用源代碼來安裝,不過要注意的是,必須確保系統已經安裝了依賴的Perl軟件包:服務器
shell> perl -MCPAN -e 'install DBI' shell> perl -MCPAN -e 'install DBD::mysql' shell> perl -MCPAN -e 'install Term::ReadKey'
順便說一下,我在安裝某些Perl模塊的時候,出現相似下面的錯誤提示:ide
Can’t locate object method 「install」 via package 「…」
若是你也遇到了相似的問題,能夠進入到Perl命令行安裝:函數
shell> perl -MCPAN -e shell cpan> install ...
安裝Percona Toolkit的剩餘步驟就是Perl軟件的固定打法了:this
shell> perl Makefile.PL shell> make shell> make install
前戲進行到這裏應該能夠了,下面讓咱們直搗黃龍,看看如何解決問題:操作系統
MySQL主從服務器數據一致性的核對命令行
經過在主服務器上運行pt-table-checksum,它會經過一系列的MySQL函數計算每一個表的散列值,利用主從複製關係,把一樣的計算過程在從服務器上重放,從而就拿到了主從服務器各自的散列值,只要比較散列值是否相同就OK了。
這裏面有兩點須要說明:
計算表的散列值時,pt-table-checksum並非直接計算整個表的散列值,而是分塊計算,這樣就避免了形成從服務器長時間的延遲。
由於經過MySQL函數計算散列的過程須要在從服務器上重放,因此主從複製的格式必須是基於STATEMENT的,不能是基於ROW的。
實際操做時的命令大體以下:
shell> pt-table-checksum \ --replicate=percona.checksums \ --host=<MASTER_HOST> \ --user=<MASTER_USER> \ --password=<MASTER_PASSWORD>
說明:replicate選項指定告終果保存到哪一個庫和表中,若是你願意,能夠手動查詢:
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks FROM percona.checksums WHERE ( master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)) GROUP BY db, tbl;
BTW:多數狀況下,只要比較「master_crc <> this_crc」就能夠了。
MySQL主從服務器數據一致性的修復
經過在主服務器上運行pt-table-sync,它會重建數據,數據經過複製從主服務器同步到從服務器,從而修復了一致性,在操做過程當中,能夠利用pt-table-checksum的結果。
shell> pt-table-sync \ --execute \ --replicate=percona.checksums \ --charset=<CHARSET> \ --host=<MASTER_HOST> \ --user=<MASTER_USER> \ --password=<MASTER_PASSWORD>
說明:由於pt-table-sync會重建數據,因此有必定的風險,最好提早備份好數據。若是仍然不放心,可使用它提供的「print」選項,它會打印出相應的SQL,你能夠審查一下到底執行了那些操做,而後經過手動執行來完成同步。
本文例子中,咱們爲了方便,在運行Percona Toolkit命令的時候直接鍵入了密碼等敏感信息,這在不少時候是不安全的,好比說別人能夠經過查看命令歷史拿到密碼。還好咱們有「ask-pass」 選項能夠解決此類問題,實際上咱們還能夠更進一步,直接把密碼等敏感信息保存到配置文件中,最容易想到的配置文件是「~/.my.cnf」,此外,還有幾 個更官方的配置文件可供選擇,咱們能夠在源代碼裏看到它們的蹤跡:
default_files => [ "/etc/percona-toolkit/percona-toolkit.conf", "/etc/percona-toolkit/$program_name.conf", "$home/.percona-toolkit.conf", "$home/.$program_name.conf", ] …
俗話說:不怕賊偷,就怕賊惦記着。看待問題的態度亦是如此:不怕出問題,就怕問題潛伏在暗處窺視着你,而你卻一無所知。你們沒事兒的時候多查查主從一致性吧。