Duplicate entry '%-.64s' for key %d' (1062)错误分析
Duplicate entry '%-.64s' for key %d' (1062)错误分析
最近遇到过一次同步错误:
'Duplicate entry '%-.64s' for key %d' (1062), Error on slave: 'noerror' (0). Default database: 'test'************
后一同事分析说是因为master上使用myisam,而slave确是innodb导致,因为比较紧急,当时觉得这个解释不太合乎情理,但是由于工作太忙,跳过错误后,也就没有来得及研究,今天分析了下,觉得不应该是由于type不一致导致,因为,如果master是myisam,多行插入,如果中间有一行主键冲突,master上确实会报错误ERROR1062 (23000): Duplicate entry '8' for key1,之类的错误,并且这个错误之前的行都会插入,之后的行都不会插入,而slave上,由于是innodb,整个语句是一个事务,所以他全部行都不会插入,所以我认为理论上不会同步停止的,事实证明,他确实是这样,
实验如下:
1:证实不是type不同而导致的
master:
CREATE TABLE `myisam_test` (
`id` int(11) unsigned NOT NULL default'1',
`uid` int(11) unsigned NOT NULL default'0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM;
slave:
CREATE TABLE `myisam_test` (
`id` int(11) unsigned NOT NULL default'1',
`uid` int(11) unsigned NOT NULL default'0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
mysql> select * from myisam_test;
+----+-----+
| id | uid |
+----+-----+
| 1 | 1|
| 2 | 1|
| 3 | 1|
+----+-----+
3 rows in set (0.00 sec)
master:
insert into myisam_test values (100,1),(2,1),(101,1)
ERROR 1062 (23000): Duplicate entry '2' for key 1
master:
mysql> select * from myisam_test;
+-----+-----+
| id | uid |
+-----+-----+
| 1| 1 |
| 2| 1 |
| 3| 1 |
| 100 | 1 |
+-----+-----+
4 rows in set (0.00 sec)
slave:
mysql> select * from myisam_test;
+----+-----+
| id | uid |
+----+-----+
| 1 | 1|
| 2 | 1|
| 3 | 1|
+----+-----+
3 rows in set (0.01 sec)
这时同步没有停止,master与slave 数据确不一致了,跟我上面分析的结果一致,master key2之前的插入了,2之后的没有插入,而slave上,全部回退,这也说明,如果type不一致,后果其实还是蛮严重的!
2:回现错误
google一把,网上有人说,这个错误,是由于master上主键冲突,但是slave上确没有冲突,语句执行正常导致,其实仔细看下报的错误”Erroron slave: 'no error' (0)“ 我们也可以分析“他是:错误在slave没有出现错误!”
master and slave:
mysql> select * from myisam_test;
+----+-----+
| id | uid |
+----+-----+
| 1 | 1|
| 2 | 1|
| 3 | 1|
+----+-----+
3 rows in set (0.00 sec)
slave:
强制破环一致,删除主键为2的
delete from myisam_test where id=2;
mysql> select * from myisam_test;
+----+-----+
| id | uid |
+----+-----+
| 1 | 1|
| 3 | 1|
+----+-----+
2 rows in set (0.00 sec)
master:
mysql> insert into myisam_test values(100,1),(2,1),(101,1)
ERROR 1062 (23000): Duplicate entry '2' for key 1
mysql> select * from myisam_test;
+-----+-----+
| id | uid |
+-----+-----+
| 1| 1 |
| 2| 1 |
| 3| 1 |
| 100 | 1 |
+-----+-----+
4 rows in set (0.01 sec)
slave:
这个时候,由于主键没有为2的,在slave上,上面insert语句,不会报错,结果如下:
mysql> select * from myisam_test;
+-----+-----+
| id | uid |
+-----+-----+
| 1| 1 |
| 2| 1 |
| 3| 1 |
| 100 | 1 |
| 101 | 1 |
+-----+-----+
5 rows in set (0.01 sec)
而这时候,重现了上次出的那个问题:
Last_Error: Query caused different errors onmaster and slave. Error on master: 'Duplicate entry '%-.64s' forkey %d' (1062), Error on slave: 'no error' (0). Default database:'test'. Query: 'insert into myisam_test values(100,1),(2,1),(101,1)'
这就很明显了,当错误在master上发生错误时记录的binlog,而在slave确没有发生错误,就会出现导致同步中断的那个错误,跟type没有关系!当然如果主上是innodb type,那么他肯定不会出现上面问题,因为那Duplicate会直接回滚,根本不会记录binlog,故不可能出现上面错误!
其实这个错误,也在让我了解了一点,
# at 6864
#101205 21:13:30 server id 111613321 end_log_pos6979 Query thread_id=29 exec_time=0 error_code=1062
SET TIMESTAMP=1291554810;
对于error_code=1062错误的binlog,他其实在slave也会执行,这个error_code只是告诉slave,这条语句是会报1062错误,而slave确会像正常语句那样执行!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论