mysql主從數據不一致問題解決

問題

要解決問題就是怎麼對比不一致,然後在不影響業務的情況下,修復數據不一致的問題,把從庫缺少的數據補上
下面是能想到和找到的幾個方案
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
1
2
之前的錯誤,導致主從複製有問題,去從庫查看主動狀態,調整是得主從正常。

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

下面繼續在主庫的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 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數據備份一下,因爲會對主庫有些寫操作,有一點風險。

主庫服務器執行

[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_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 怎麼建立用戶,用戶應該給予怎樣的權限

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章