匿名通过本文主要向大家介绍了MySQL,GTID ,错误处理等相关知识,希望本文的分享对您有所帮助
MySQL GTID是在传统的mysql主从复制的基础之上演化而来的产物,即通过UUID加上事务ID的方式来确保每一个事物的唯一性。这样的操作方式使得我们不再需要关心所谓的log_file和log_Pos,只是简单的告诉从库,从哪个服务器上去找主库就OK了。简化了主从的搭建以及failover的过程,同时比传统的复制更加安全可靠。由于GTID是连续没有空洞的,因此主从库出现数据冲突时,可以通过注入空事物的方式进行跳过。本文主要讲述GTID主从架构的错误处理方式。
一、GTID的相关特性
配置MySQL GTID 主从复制
基于mysqldump搭建gtid主从
二、GTID如何跳过事务冲突
很多无法预料的情形导致mysql主从发生事务冲突,主从失败或停止的情形,即需要修复主从
对于GTID方式的主从架构而言,更多的是处理事务冲突来修复主从
GTID不支持通过传统设置sql_slave_skip_counter方法来跳过事务
方法:通过注入空事务来填补事务空洞,等同于传统复制的(set global sql_slave_skip_counter = 1)
步骤:
stop slave;
set gtid_next='xxxxxxx:N'; --指定下一个事务执行的版本,即想要跳过的GTID
begin;
commit; --注入一个空事物
set gtid_next='AUTOMATIC' --自动的寻找GTID事务。
start slave; --开始同步三、GTID事务冲突的几种常见类型
1、主库新增记录,从库提示主键冲突
2、主库对象可更新,从库无对应的对象可更新
3、主库对象可删除,从库无对应的对象可删除
4、通过延迟从修复主库意外删除的对象
5、主库日志被purged的情形四、示例演示
当前演示的主从架构图 # mysqlrplshow --master=root:pass@192.168.1.233:3306 --discover-slaves-login=root:pass --verboseWARNING: Using a password on the command line interface can be insecure. # master on 192.168.1.233: ... connected. # Finding slaves for master: 192.168.1.233:3306 # Replication Topology Graph 192.168.1.233:3306 (MASTER) | +--- 192.168.1.245:3306 [IO: Yes, SQL: Yes] - (SLAVE) | +--- 192.168.1.247:3306 [IO: Yes, SQL: Yes] - (SLAVE)(root@192.168.1.233)[tempdb]>show slave hosts;+-----------+---------------+------+-----------+--------------------------------------+| Server_id | Host | Port | Master_id | Slave_UUID | +-----------+---------------+------+-----------+--------------------------------------+| 245 | 192.168.1.245 | 3306 | 233 | 78336cdc-8cfb-11e6-ba9f-000c29328504 || 247 | 192.168.1.247 | 3306 | 233 | 13a26fc1-555a-11e6-b5e0-000c292e1642 | +-----------+---------------+------+-----------+--------------------------------------+--演示的mysql版本 (root@192.168.1.233)[tempdb]>show variables like 'version';+---------------+------------+| Variable_name | Value | +---------------+------------+| version | 5.7.12-log | +---------------+------------+--查看gtid是否开启 (root@192.168.1.233)[tempdb]>show variables like '%gtid_mode%';+---------------+-------+| Variable_name | Value | +---------------+-------+| gtid_mode | ON | +---------------+-------+--主库上面可以看到基于gtid的dump线程,如下 (root@192.168.1.233)[tempdb]>show processlist;+----+------+-----------------------+--------+------------------+------+| Id | User | Host | db | Command | Time | +----+------+-----------------------+--------+------------------+------+| 17 | repl | node245.edq.com:52685 | NULL | Binlog Dump GTID | 2738 | | 18 | repl | node247.edq.com:33516 | NULL | Binlog Dump GTID | 2690 || 24 | root | localhost | tempdb | Query | 0 | +----+------+-----------------------+--------+------------------+------+
1、从库报主键重复(Errno: 1062)
(root@Master)[tempdb]>create table t1 (
-> id tinyint not null primary key,ename varchar(20),blog varchar(50));
(root@Master)[tempdb]>insert into t1
-> values(1,'leshami','http://blog.csdn.net/leshami');
(root@Master)[tempdb]>insert into t1
-> values(2,'robin','http://blog.csdn.net/robinson_0612');
(root@Master)[tempdb]>set sql_log_bin=off;
(root@Master)[tempdb]>delete from t1 where ename='robin';
(root@Master)[tempdb]>set sql_log_bin=on;
(root@Master)[tempdb]>insert into t1
-> values(2,'robin','http://blog.csdn.net/robinson_0612');
-- 从库状态报错,提示重复的primary key
(root@Slave)[tempdb]>show slave status \G
*************************** 1. row ***************************Last_Errno: 1062Last_Error: Could not execute Write_rows event on table tempdb.t1; Duplicate entry '2' for key 'PRIMARY',
Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY;
the event's master log node233-binlog.000004, end_log_pos 4426
Retrieved_Gtid_Set: 1b64c25d-8d2b-11e6-9ac0-000c29b82d0d:76-90
Executed_Gtid_Set: 1b64c25d-8d2b-11e6-9ac0-000c29b82d0d:1-89
Auto_Position: 1
-- 如下解决方案,可以通过删除重库的这条记录
(root@Slave)[tempdb]>stop slave;
(root@Slave)[tempdb]>delete from t1 where ename='robin';
(root@Slave)[tempdb]>start slave;
(root@Slave)[tempdb]>show slave status \G
*************************** 1. row ***************************
Retrieved_Gtid_Set: 1b64c25d-8d2b-11e6-9ac0-000c29b82d0d:76-90
Executed_Gtid_Set: 1b64c25d-8d2b-11e6-9ac0-000c29b82d0d:1-90,
78336cdc-8cfb-11e6-ba9f-000c29328504:1 --这里多了一个GTID,注意这个是从库上执行的,这里的UUID跟IP 245的UUID一致
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
(root@Slave)[tempdb]>show variables like '%uuid%';
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| server_uuid | 78336cdc-8cfb-11e6-ba9f-000c29328504 |
+---------------+--------------------------------------+2、从库报找不到对应的被更新的记录(Errno: 1032)
--首先在从库上删除leshami这条记录
(root@Slave)[tempdb]>delete from t1 where ename='leshami';
--接下来再主库尝试更新leshami这条记录
(root@Master)[tempdb]>update t1 set
-> blog='http://blog.csdn.net/robinson_0612' where ename='leshami';Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- 查看从库状态
(root@Slave)[tempdb]>show slave status \G*************************** 1. row ***************************Last_SQL_Errno: 1032
Last_SQL_Error: Could not execute Update_rows event on table tempdb.t1; Can't find record in 't1', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log node233-binlog.000004, end_log_pos 4769Retrieved_Gtid_Set: 1b64c25d-8d2b-11e6-9ac0-000c29b82d0d:76-91
Executed_Gtid_Set: 1b64c25d-8d2b-11e6-9ac0-000c29b82d0d:1-90, 78336cdc-8cfb-11e6-ba9f-000c29328504:1-2-- 通过mysqlbinlog在主服务器上寻找报错的binglog日志文件及位置,找到对应的SQL语句,如下所示
-- update中的where后面的部分为更新前的数据,set部分为更新后的数据,因此可以将更新前的数据插入到从库# mysqlbinlog --no-defaults -v -v --base64-output=DECODE-ROWS /data/node233-binlog.000004|grep -A '10' 4769#161009 13:46:34 server id 233 end_log_pos 4769 CRC32 0xb60df74e Update_rows: table id 147 flags: STMT_END_F### UPDATE `tempdb`.`t1`### WHERE### @1=1 /* TINYINT meta=0 nullable=0 is_null=0 */### @2='leshami' /* VARSTRING(20) meta=20 nullable=1 is_null=0 */### @3='http://blog.csdn.net/leshami' /* VARSTRING(50) meta=50 nullable=1 is_null=0 */### SET### @1=1 /* TINYINT meta=0 nullable=0 is_null=0 */### @2='leshami' /* VARSTRING(20) meta=20 nullable=1 is_null=

