Mysql基於binlog方式進行數據同步常見問題解決方案匯總


Mysql基於binlog方式進行數據同步常見問題解決方案匯總​

0、前置信息

0.1、集群信息

服務器連接信息: 192.168.91.131(master) 192.168.91.132(slave1) 192.168.91.133(slave2) ​ 使用ssh方式訪問服務器: ssh root@192.168.91.* 輸入對應密碼訪問

0.2、從庫數據導入

192.168.91.131命令行窗口下直接執行數據庫表數據導入

mysqldump --default-character-set=utf8mb4 --host=192.168.91.131 -uroot -p123456 --opt --set-gtid-purged=OFF 從庫需要導入數據的數據庫名 | mysql --host=從庫IP地址 --port=3306 -uroot -p123456 --default-character-set=utf8mb4 -C 從庫需要導入數據的數據庫名

說明: 使用此方式進行數據導入時,保證目標數據庫中數據表與源數據庫中數據表一致,同時,目標數據庫中數據表保證為空表

0.3 、從庫設置同步過濾規則

---- 從庫設置同步過濾規則(在my.cnf中設置,對應k8s在配置字典中配置) ---- replicate_wild_do_table = 要同步的數據庫名.%
replicate_wild_ignore_table = 要忽略的數據庫名.%

1、數據同步(binlog方式)

主、從庫使用binlog方式同步數據,操作步驟:

1.1、主、從庫修改數據庫配置

1> 修改mysql配置文件

vi /etc/my.cnf

添加如下內容:

# 服務編號(與其它節點不沖突即可) server_id=1 log_bin=binlog binlog_format=ROW

2> 重啟MySQL數據庫

systemctl restart mysqld.service

1.2、主庫操作說明

1> 主庫創建復制賬號,命令如下
mysql> CREATE USER repl IDENTIFIED BY '123456'; mysql> GRANT SELECT, SHOW VIEW, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'%'; mysql> FLUSH PRIVILEGES;

2> 獲取主庫的binlog文件和當前位置

mysql> show master status;

獲取主庫的binlog文件和當前位置,即查詢結果的 File、Position 字段,例如:File字段值為 binlog.XXXXXXXX,Position 字段值為 YYYYYYYY

1.3、從庫關聯同步主庫數據

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.91.131', MASTER_USER = 'repl', MASTER_PASSWORD = '123456', MASTER_PORT = 3306, MASTER_LOG_FILE='binlog.XXXXXXXX', MASTER_LOG_POS=YYYYYYYY; ​ mysql> start slave; mysql> show slave status;

2、常見問題匯總及解決

2.1、主、從庫數據表字符集不一致

2.1.1、報錯信息

Last_SQL_Errno: 1677
Last_SQL_Error: Column 1 of table 'XXX' cannot be converted from type 'varchar(150(bytes))' to type 'varchar(110(bytes))'

2.1.2、解決方案

1> 主、從庫查看數據表的字符集信息

mysql> show create table 表名;

2> 從庫執行如下命令

mysql> stop slave; mysql> alter table table_name convert to character set 主庫數據表字符集; mysql> start slave;
mysql
> show slave status;

2.2、主庫刪除從庫不存在數據

2.2.1、報錯信息

Last_Errno: 1032
Last_SQL_Error: Could not execute Delete_rows event on table XXX; Can't find record in 'XXX', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND;

2.2.2、解決方案

2.2.2.1、方案1--從庫插入不存在數據,然后開啟數據同步

1> 在從庫執行如下命令:

mysql> show slave status; 

找到Exec_Master_Log_Pos的值,例如:XXXX;Last_Error信息中的end_log_pos的值,例如:YYYYYY

2> 在主庫使用自帶的mysqlbinlog查看刪除信息:

cd /usr/bin
mysqlbinlog
--no-defaults -v -v --base64-output=DECODE-ROWS --start-position=XXXX --stop-position=YYYYYY /var/lib/mysql/binlog.000001

說明:

主庫mysqlbinlog所在文件夾位置,可以使用如下命令查找:

whereis mysqlbinlog

3> 找到刪除語句之后,在從庫插入刪除數據,例如:

insert into test values(1, 'jack');

4> 在從庫執行如下命令

mysql> start slave;
mysql> show slave status;

插入數據時,如果遇到索引沖突的問題,可參考如下操作:

mysql插入數據時,出現Duplicate entry 'XXX' for key 'XXX'的問題: 可以使用replace into, replace into是insert into的增強版: (1) 如果插入的數據不重復,執行的是insert into操作,影響1條記錄 (2) 如果插入的數據重復,執行的是update操作,影響2條記錄:先刪除舊的數據,再插入新的數據。 示例: replace into test values(1,'jack'
2.2.2.2、方案2--從庫直接跳過GTID

 1> 在從庫中執行如下命令

mysql> show slave status\G;

找到同步失敗時主庫log位置,即Exec_Master_Log_Pos的值,例如:XXXX;同時從Last_Error信息中找到同步失敗的binlog文件名,例如:binlog.000021

2> 在主庫中查詢執行如下語句

mysql> show binlog events IN 'binlog.000021' FROM XXXX limit 10;

找到XXXX對應的SESSION.GTID_NEXT值,例如:ZZZZZ

3> 在從庫中執行如下語句

mysql> stop slave; mysql> set GTID_NEXT='ZZZZZ'; mysql> begin;commit; mysql> set GTID_NEXT='AUTOMATIC'; mysql> start slave; mysql> show slave status;

上面方法只能跳過一個事務,那么對於一批事務跳過,參考如下指令:

(1)主庫執行如下語句

mysql> show master status;

根據查詢結果,找到 Executed_Gtid_Set 字段對應的值,例如:2a09ee6e-645d-11e7-a96c-000c2953a1cb:1-19345623

(2)在從庫中執行如下語句

mysql> stop slave; mysql> reset master; mysql> set global gtid_purged='2a09ee6e-645d-11e7-a96c-000c2953a1cb:1-19345623'; mysql> start slave; mysql> show slave status;

2.3、主庫更新從庫不存在數據

2.3.1、報錯信息

Last_Errno: 1032
Last_Error: Could not execute Update_rows event on table XXX; Can't find record in 'XXXX', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log binlog.0000XX, end_log_pos XXXXX

2.3.2、解決方案

1> 在從庫執行如下命令:

mysql> show slave status; # 也可使用: mysql> show slave status\G; 

找到Exec_Master_Log_Pos的值,例如:XXXX;Last_Error信息中的end_log_pos的值,例如:YYYYYY

2> 在主庫使用mysqlbinlog查看更新操作的數據:

mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS --start-position=XXXX --stop-position=YYYYYY /var/lib/mysql/binlog.000001

3> 在主庫中查看更新之后的數據,然后將這些數據導出;並在從庫執行插入語句插入數據。

4> 在主庫中查詢執行事件:

mysql> show binlog events IN 'binlog.000001' FROM XXXX limit 50;

找到XXXX對應的SESSION.GTID_NEXT值 ZZZZZ

5> 在從庫中執行如下語句

mysql> stop slave; mysql> set GTID_NEXT='ZZZZZ'; mysql> begin;commit; mysql> set GTID_NEXT='AUTOMATIC'; mysql> start slave; mysql> show slave status;

2.4、從庫連接數不足導致同步失敗

2.4.1、報錯信息

Slave_IO_State: connecting to master Last_IO_Error: MySql Host is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'

2.4.2、解決方案

1> 主、從數據庫都要查看max_connection_errors

(1) 進入主、從庫Mysql數據庫查看max_connection_errors

mysql> show variables like '%max_connect_errors%';

(2) 修改max_connection_errors的數量為1000

mysql> set global max_connect_errors = 1000;

(3) 查看是否修改成功

mysql> show variables like '%max_connect_errors%'; 

2> 在主、從庫下清理一下hosts文件

mysql> flush hosts;

2.5、主庫下caching_sha2_password插件導致連接異常

2.5.1、報錯信息

Last_IO_Error: error connecting to master 'repl@192.168.91.131:3306' - retry-time: 60 retries: 7 message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.

2.5.2、解決方案

1> 在主庫下數據庫名為 mysql下的 user表,查看 user為repl 信息

mysql> SELECT plugin FROM `mysql`.`user` where user = 'repl';

2> 修改主庫mysql下的 user表中repl對應的mysql_native_password (新舊密碼可以保持一致)

mysql> ALTER USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

2.6、主從數據同步報錯1782

2.6.1、報錯信息

Last_Errno: 1782 Last_Error: Error executing row event: '@@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.'

2.6.2、解決方案

在從庫中執行如下命令:

mysql> stop slave sql_thread; mysql> set GLOBAL GTID_MODE = ON_PERMISSIVE; mysql> set GLOBAL GTID_MODE = OFF_PERMISSIVE; mysql> set GLOBAL GTID_MODE = OFF; mysql> start slave sql_thread; mysql> start slave; mysql> show slave status;

2.7、主從數據同步報錯1781

2.7.1、報錯信息

Last_Errno: 1781 Last_Error: @@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.

2.7.2、解決方案

在從庫中執行如下命令:

mysql> set GLOBAL GTID_MODE = OFF_PERMISSIVE; mysql> set GLOBAL GTID_MODE = ON_PERMISSIVE; mysql> set GLOBAL GTID_MODE = ON; mysql> start slave; mysql> show slave status;

2.8、從庫存在數據,主庫插入相同數據同步失敗

說明:

此種情況是從庫存在數據,導致主庫在插入相同數據時,從庫數據同步報錯。

2.8.1、報錯信息

Last_Errno: 1062 Last_Error: Could not execute Write_rows event on table XXXX.xxx; Duplicate entry 'XXX' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log binlog.XXXXXXX, end_log_pos XXXXXXX

2.8.2、解決方案

針對此種情況,保證以主庫數據為主,同時刪除從庫數據時需要考慮從庫表數據主鍵是否為自增。

mysql> stop slave; mysql> delete from XXXX.xxx where 主鍵字段='XXX'; mysql> start slave; mysql> show slave status;

2.9、中繼日志損壞

2.9.1、報錯信息

Last_SQL_Error: Error initializing relay log position: I/O error reading the header from the binary log Last_SQL_Error: Error initializing relay log position: Binlog has bad magic number; It's not a binary log file that can be used by this version of MySQL

2.9.2、解決方案

說明:找到同步的binlog和POS點,然后重新做同步,這樣就可以有新的中繼日志

1> 在從庫查找執行的中繼日志Relay_Master_Log_File和Exec_Master_Log_Pos節點

mysql> show slave status\G;

獲取 Relay_Master_Log_File 值(例如:binlog.xxxxx) 和 Exec_Master_Log_Pos 值(例如:YYYYYY)

2> 在從庫執行如下命令

mysql> stop slave; mysql> CHANGE MASTER TO MASTER_LOG_FILE='binlog.xxxxx', MASTER_LOG_POS=YYYYYY; mysql> start slave; mysql> show slave status\G;

~~~~~~~~~~~~~~~~~~~~~未完待續~~~~~~~~~~~~~~~~~~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM