[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