Quantcast
Channel: CodeSection,代码区,数据库(综合) - CodeSec
Viewing all articles
Browse latest Browse all 6262

常见GTID主从复制报错及处理思路 GTID主从复 GTID报错 GTID报错处理

$
0
0
测试环境(已经事先搭建好GTID主从环境)
mysql5.7.16--01 3307 主
MySQL5.7.16--02 3308 从
准备:
在主库建表,插入测试数据
CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into t(name) values('小米'),('小郭'),('小华'),('小欧');
root@localhost:mysql3307.sock [test]>select * from t;
+----+--------+
| id | name |
+----+--------+
| 1 | 小米 |
| 2 | 小郭 |
| 3 | 小华 |
| 4 | 小欧 |
+----+--------+
4 rows in set (0.00 sec)
1、从库复制报错1050
执行show slave status\G查看错误信息
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1050
Last_Error: Error 'Table 't' already exists' on query. Default database: 'test'. Query: 'CREATE TABLE `t` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
sql线程中断,报错信息显示t表在从库上已经存在,IO线程将relay-log解析回放的过程中该事务无法执行
通过查看Executed_Gtid_Set参数
主库:
root@localhost:mysql3307.sock [test]>show master status;
+------------------+----------+--------------+------------------+-------------------------------------------------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------------------------------------------------------------------------+
| mysql-bin.000007 | 1143 | | | ac06a58c-cd84-11e6-bdf1-525400a9938f:1-37,
c8e2d47f-cd6e-11e6-905c-525400a9938f:1-8 |
+------------------+----------+--------------+------------------+-------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
从库:
Executed_Gtid_Set: ac06a58c-cd84-11e6-bdf1-525400a9938f:1-35,
从库在35(包含35)之前的事务都已经正常执行完成,而主库已经执行到事务37,说明事务36在从库上没有正常执行,事务36就是报错的DML
语句。
所以思路很简单直接删除从库的t表,让事务36得到正常执行就能解决问题。
从库:
drop table t;
start slave;
show slave status\G 查看SQL和IO线程都为yes,确认修复
2、1062主键冲突(适合解决少数量主键冲突)
Last_Errno: 1062
Last_Error: Could not execute Write_rows event on table test.t; Duplicate entry '4' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY;
the event's master log mysql-bin.000007, end_log_pos 1375
接下来我们可以在主库上看下binlog执行了什么语句导致的
mysqlbinlog --base64-output=decode-row -v -v mysql-bin.000007 >07.sql
#161229 17:56:35 server id 1003307 end_log_pos 1375 CRC32 0xdea6ed27 Write_rows: table id 122 flags: STMT_END_F
### INSERT INTO `test`.`t`
### SET
### @1=4 /* INT meta=0 nullable=0 is_null=0 */
### @2='大神v' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
# at 1375
#161229 17:56:35 server id 1003307 end_log_pos 1406 CRC32 0x12dcd47c Xid = 144
COMMIT/*!*/;
主库:
root@localhost:mysql3307.sock [test]>select * from t where id=4;
+----+---------+
| id | name |
+----+---------+
| 4 | 大神v |
+----+---------+
1 row in set (0.00 sec)
从库:
root@localhost:mysql3308.sock [test]>select * from t where id=4;
+----+--------+
| id | name |
+----+--------+
| 4 | 小欧 |
+----+--------+
1 row in set (0.00 sec)
从库主键4已经存在
修复:
delete from t where id=4;
start slave;
3、更新找不到记录 1032报错
故意将主从数据不一致
root@localhost:mysql3307.sock [test]>select * from t;
+----+---------+
| id | name |
+----+---------+
| 1 | 小米 |
| 2 | 小郭 |
| 3 | 小华 |
| 4 | 大神v |
| 5 | 戴斯 |
+----+---------+
5 rows in set (0.00 sec)
root@localhost:mysql3308.sock [test]>select * from t;
+----+---------+
| id | name |
+----+---------+
| 1 | 小米 |
| 2 | 小郭 |
| 3 | 小华 |
| 4 | 大神v |
+----+---------+
4 rows in set (0.00 sec)
update t set name='小鸡' where id=5;
报错信息:
Last_SQL_Errno: 1032
Last_SQL_Error: Could not execute Update_rows event on table test.t; Can't find record in 't',
Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000007, end_log_pos 1650
思路和之前一样,查看binlog锁定主库执行的sql
mysqlbinlog --base64-output=decode-row -v -v mysql-bin.000007 >07.sql
#161229 18:19:15 server id 1003307 end_log_pos 1650 CRC32 0x0b598bd9 Update_rows: table id 122 flags: STMT_END_F
### UPDATE `test`.`t`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='戴斯' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
### SET
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='小鸡' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
# at 1650
#161229 18:19:15 server id 1003307 end_log_pos 1681 CRC32 0x781b6ae1 Xid = 153
COMMIT/*!*/;
知道是在主库执行了对id=5的行update导致,查看下从库没有id=5的主键,这个时候我们自己手动加一条上去
修复:
insert into t(id,name) values(5,'睡觉睡觉');
start slave;
4. delete 找不到记录 1032报错
delete from t where id=5;
Last_SQL_Errno: 1032
Last_SQL_Error: Could not execute Delete_rows event on table test.t; Can't find record in 't',
Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000007, end_log_pos 1912
这个错误有2种解决方式:
方法一、还是前面的思路,在binlog中根据log_pos找到delete语句
#161229 18:29:35 server id 1003307 end_log_pos 1912 CRC32 0x8166304d Delete_rows: table id 122 flags: STMT_END_F
### DELETE FROM `test`.`t`
### WHERE
### @1=5 /* INT meta=0 nullable=0 is_null=0 */
### @2='小鸡' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
# at 1912
#161229 18:29:35 server id 1003307 end_log_pos 1943 CRC32 0xa1a89910 Xid = 155
COMMIT/*!*/;
是删除主键id=5的行导致的报错,思路就是在从库插入一条id=5的行,让事务能够顺利执行下去,就能解决报错
修复:
insert into t(id,name) values(5,'小感动');
start slave;
方法二:执行跳过这个事务,因为是delete操作,跳过不会影响主从数据一致性
show slave status\G
查看参数:Retrieved_Gtid_Set Executed_Gtid_Set
Retrieved_Gtid_Set: ac06a58c-cd84-11e6-bdf1-525400a9938f:1-77,
Executed_Gtid_Set: ac06a58c-cd84-11e6-bdf1-525400a9938f:1-61,
我们看到从库已经将事务61(包含61)之前的事务全部完成,主库的source_id:ac06a58c-cd84-11e6-bdf1-525400a9938f 1-77是主库执行到的事务ID
说明从库在执行事务ID62的时候无法执行,造成主从不同步,所以直接跳过事务ID 62
步骤:
stop slave;
set gtid_next='ac06a58c-cd84-11e6-bdf1-525400a9938f:62';
begin;commit;
set gtid_next='automatic';
start slave;
结语:这是几种常见的小故障,主要是一个处理的思路,一切还是以生存环境为准,多看,多想,最重要的还是多操作。

Viewing all articles
Browse latest Browse all 6262

Trending Articles