歡迎您光臨本站 註冊首頁

Duplicate entry '%-.64s' for key %d' (1062)錯誤分析

←手機掃碼閱讀     火星人 @ 2014-03-03 , reply:0

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確會像正常語句那樣執行!

[火星人 ] Duplicate entry '%-.64s' for key %d' (1062)錯誤分析已經有424次圍觀

http://coctec.com/docs/service/show-post-2293.html