1. 程式人生 > >[mysql]一次主從資料不一致的問題解決過程

[mysql]一次主從資料不一致的問題解決過程

版權宣告:本文為orangleliu (http://blog.csdn.net/orangleliu/)原創文章,自由傳播,文章轉載請宣告, 多謝。 https://blog.csdn.net/lzz957748332/article/details/46532215

之前一篇: 主從更換ip之後重新建立同步 情況時這樣的 昨天晚上主動2個機器都遷移了,然後今天才把主動重新連線上,但是從庫的偏移量是從今天當前時刻開始的,也就是說雖然現在主動看似正常,其實是少了昨天的部分資料,由於從庫的資料丟失了,早晚還是要填坑的。

問題

  • 要解決問題就是怎麼對比不一致,然後在不影響業務的情況下,修復資料不一致的問題,把從庫缺少的資料補上

下面是能想到和找到的幾個方案 1 從新從0開始同步,雖然對主庫的使用沒有影響,但是那麼大的資料量,對效能,網路影響有點大,資料丟失的應該很少 2 主庫dump資料,鎖庫,然後同步,不好。 影響業務使用 3 percona-toolkit 中的工具來校驗和同步,從介紹上來看是符合現在的情況的,使用上還需要學習和認識才行。

下面是幾個參考連結

操作過程

只把過程和用到的東西解釋了下,有些引數選項等還需要查閱文件。兩臺機器都是centos6.5 mysql版本都是5.6 , 由於是線上環境,這裡ip和密碼等敏感資訊修改了下。

  • 主 192.168.1.100
  • 從 192.168.1.98
  • 修復資料庫名 radius

工具安裝

主庫伺服器安裝

#安裝依賴包
# yum install perl-DBI  perl-DBD-MySQL  perl-TermReadKey perl-Time-HiRes

#安裝工具
# wget percona.com/get/percona-toolkit.tar.gz
# tar zxvf percona-toolkit-2.2.14.tar.gz
# cd percona-toolkit-2.2.14
# perl Makefile.PL && make && make install 

校驗資料一致性

建立使用者並授權

注意這裡要在主從建立一個同名的使用者,可以從主庫訪問從庫,主庫本地可以訪問主庫。工具的使用都是在主庫的伺服器上進行,使用 pt-table-checksum校驗資料一致性。

從庫mysql操作

GRANT SELECT,PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'checksums'@'192.168.1.100' IDENTIFIED BY 'slavecheck';

flush privileges;

主庫mysql操作

GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'checksums'@'192.168.1.100' IDENTIFIED BY 'slavecheck';

GRANT SELECT,INSERT,UPDATE,DELETE ON radius.checksums TO 'checksums'@'192.168.1.100';

flush privileges;

校驗時候需要在主mysql 中新建一張表,新建使用者需要有讀寫的許可權,這裡是把校驗表建立在radius庫中。

pt-table-checksum 校驗

校驗是在主庫伺服器上進行的

主庫shell中執行
pt-table-checksum h='192.168.1.100',u='checksums',p='slavecheck',P=3306 -d radius --nocheck-replication-filters --replicate=radius.checksums

--nocheck-replication-filters :不檢查複製過濾器,建議啟用。後面可以用--databases來指定需要檢查的資料庫。
--no-check-binlog-format      : 不檢查複製的binlog模式,要是binlog模式是ROW,則會報錯。
--replicate-check-only :只顯示不同步的資訊。
--replicate=    :把checksum的資訊寫入到指定表中,建議直接寫到被檢查的資料庫當中。 
--databases=    :指定需要被檢查的資料庫,多個則用逗號隔開。
--tables=       :指定需要被檢查的表,多個用逗號隔開
h=192.168.1.100 :Master的地址
u=checksums         :使用者名稱
p=slavecheck        :密碼
P=3306          :埠

這個指令碼在主庫機器上執行,會自動找到從庫地址,並用相同的使用者登入,然後對比。

–replicate 選項是建立一個表來儲存對比資訊,這個表一定要能同步到從庫中,如果checksums使用者沒有建表許可權,請自行建立好表

建表語句

CREATE TABLE IF NOT EXISTS `radius`.`checksums` (
     db             CHAR(64)     NOT NULL,
     tbl            CHAR(64)     NOT NULL,
     chunk          INT          NOT NULL,
     chunk_time     FLOAT            NULL,
     chunk_index    VARCHAR(200)     NULL,
     lower_boundary TEXT             NULL,
     upper_boundary TEXT             NULL,
     this_crc       CHAR(40)     NOT NULL,
     this_cnt       INT          NOT NULL,
     master_crc     CHAR(40)         NULL,
     master_cnt     INT              NULL,
     ts             TIMESTAMP    NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     PRIMARY KEY (db, tbl, chunk),
     INDEX ts_db_tbl (ts, db, tbl)
  ) ENGINE=INNODB;

我這裡手動建立好表之後出現瞭如下的錯誤

6-16T16:10:48 The --replicate table `radius`.`checksums` exists on the master but but it has problems on these replicas:
Table radius.checksums does not exist on replica localhost.localdomain

之前的錯誤,導致主從複製有問題,去從庫檢視主動狀態,調整是得主從正常。

錯誤解決完了繼續執行(結果有省略)

下面繼續在主庫的shell上檢查
[[email protected] portal]# pt-table-checksum h='192.168.1.100',u='checksums',p='slavecheck',P=3306 -d radius --nocheck-replication-filters --replicate=radius.checksums
            TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
06-16T16:50:21      0      1     8379       4       0   0.322 radius.account_account
06-16T16:50:21      0      1    11429       1       0   0.278 radius.account_mac
06-16T16:50:21      0      1    63747       1       0   0.329 radius.account_smslog
06-16T16:50:21      0      0        0       1       0   0.016 radius.auth_group
06-16T16:50:21      0      0        0       1       0   0.013 radius.auth_group_permissions
06-16T16:50:22      0      0       27       1       0   0.265 radius.auth_permission
06-16T16:50:22      0      1     8384       1       0   0.273 radius.auth_user
...
...

出現這種結果,說明已經check了,diffs一欄有不同,說明那些表資料不一致. 現在登入從庫的mysql,執行如下語句

mysql> select * from radius.checksums where master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc) \G
*************************** 1. row ***************************
            db: radius
           tbl: account_account
         chunk: 2
    chunk_time: 0.028065
   chunk_index: PRIMARY
lower_boundary: 1847
upper_boundary: 9225
      this_crc: 4f43a2
      this_cnt: 7336
    master_crc: 9235f7a2
    master_cnt: 7379
            ts: 2015-06-16 17:00:31

一共有8條記錄,這8張表資料不一致。 大概能看出來缺少了多少資料等。

修復不一致資料

修復不一致資料使用pt-table-sync 工具,使用pt-table-checksum工具的結果。不過這裡還是有些坑。在修復之前最好把主mysql資料備份一下,因為會對主庫有些寫操作,有一點風險。

主庫伺服器執行

[[email protected] portal]# pt-table-sync --execute --replicate radius.checksums --sync-to-master h="192.168.1.98",P=3306,u="checksums",p="slavecheck" --ignore-tables radacct,django_session
DBI connect(';host=124.88.52.100;port=3306;mysql_read_default_group=client','checksums',...) failed: Access denied for user 'checksums'@'124.88.52.100' (using password: YES) at /usr/local/bin/pt-table-sync line 2220
但是直接用mysql連線就沒問題

最後查了下文件,發現還是使用者許可權的問題。 從庫操作

mysql> GRANT all ON radius.* TO 'checksums'@'192.168.1.100';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

主庫操作

mysql> GRANT all ON radius.* TO 'checksums'@'192.168.1.100';
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

新增增刪改查許可權其實就夠了 ,我這偷懶下。。

錯誤基本解決完了

修復資料

先修復一個不重要的表來實驗下(主庫操作)

pt-table-sync --execute --replicate radius.checksums --sync-to-master h=192.168.1.98,P=3306,u=checksums,p="slavecheck"  --tables account_smslog,radcheck --print 

修復完成在執行一次check 主庫操作

pt-table-checksum h='192.168.1.100',u='checksums',p='slavecheck',P=3306 -d radius --nocheck-replication-filters --replicate=radius.checksums

在從庫mysql中檢查下

mysql> select * from radius.checksums where master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc) \G

的確少了2張表,說明已經修復好了

接著把其他表修復,然後檢查下是否有問題就OK了。

小結

這裡主要的問題就是 1 指令碼在那裡執行(都是在主庫伺服器,從庫只是檢查下結果) 2 怎麼建立使用者,使用者應該給予怎樣的許可權

--------------------- 本文來自 orangleliu 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/orangleliu/article/details/46532215?utm_source=copy