[mysql]一次主從資料不一致的問題解決過程,mysql主從
之前一篇: 主從更換ip之後重建立立同步
情況時這樣的
昨天晚上主動2個機器都遷移了,然後今天才把主動重新串連上,但是從庫的位移量是從今天當前時刻開始的,也就是說雖然現在主動看似正常,其實是少了昨天的部分資料,由於從庫的資料丟失了,早晚還是要填坑的。
問題
- 要解決問題就是怎麼對比不一致,然後在不影響業務的情況下,修複資料不一致的問題,把從庫缺少的資料補上
下面是能想到和找到的幾個方案
1 從新從0開始同步,雖然對主庫的使用沒有影響,但是那麼大的資料量,對效能,網路影響有點大,資料丟失的應該很少
2 主庫dump資料,鎖庫,然後同步,不好。 影響業務使用
3 percona-toolkit 中的工具來校正和同步,從介紹上來看是符合現在的情況的,使用上還需要學習和認識才行。
下面是幾個參考連結
- percona-toolkit工具 官方地址
- MySQL主從伺服器資料一致性的核對與修複 簡單描述下過程
- 用pt-table-checksum校正資料一致性 描述工具原理
- 用pt-table-sync修複不一致的資料 描述了工具原理
操作過程
只把過程和用到的東西解釋了下,有些參數選項等還需要查閱文檔。兩台機器都是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上檢查[root@localhost 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 TABLE06-16T16:50:21 0 1 8379 4 0 0.322 radius.account_account06-16T16:50:21 0 1 11429 1 0 0.278 radius.account_mac06-16T16:50:21 0 1 63747 1 0 0.329 radius.account_smslog06-16T16:50:21 0 0 0 1 0 0.016 radius.auth_group06-16T16:50:21 0 0 0 1 0 0.013 radius.auth_group_permissions06-16T16:50:22 0 0 27 1 0 0.265 radius.auth_permission06-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: PRIMARYlower_boundary: 1847upper_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資料備份一下,因為會對主庫有些寫操作,有一點風險。
主程式庫伺服器執行
[root@localhost 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_sessionDBI 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筆記本” 部落格,轉載請務必保留此出處http://blog.csdn.net/orangleliu/article/details/46532215 作者orangleliu 採用署名-非商業性使用-相同方式共用協議