ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'

現象:

MySQL 主從切換後,新的master上寫入數據報主鍵衝突.錯誤如下:

ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'


原因:

主從切換後只有一張表有問題,其它的表都正常。

由於使用了replace into 方式插入導致新插入數據,導致slave上表的AUTO_INCREMENT小於Master。

在slave切換爲master後,新插入的數據導致主鍵衝突。



故障重現:

1.創建表t(id 列自增,a列爲唯一索引)
mysql> CREATE TABLE `t` (  
`id` int(11) NOT NULL AUTO_INCREMENT,  
`a` int(11) DEFAULT '0', 
 `b` int(11) DEFAULT '0',  
 PRIMARY KEY (`id`), 
  UNIQUE KEY `a` (`a`))
ENGINE=InnoDB  DEFAULT CHARSET=utf8;
Query OK, 0 rows affected (0.01 sec)


2.插入三條數據
mysql> insert into t (a,b)values(1,1),(2,2),(3,3);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0


3.查看t表中的數據
mysql> select  * from t;
+----+------+------+
| id | a    | b    |
+----+------+------+
|  1 |    1 |    1 |
|  2 |    2 |    2 |
|  3 |    3 |    3 |
+----+------+------+
3 rows in set (0.00 sec)


4.用replace插入兩條新數據
mysql> replace into t (a,b)values(3,30);
Query OK, 2 rows affected (0.01 sec)


mysql> replace into t (a,b)values(3,300);
Query OK, 2 rows affected (0.01 sec)


mysql> select * from t;
+----+------+------+
| id | a    | b    |
+----+------+------+
|  1 |    1 |    1 |
|  2 |    2 |    2 |
|  5 |    3 |  300 |
+----+------+------+
3 rows in set (0.00 sec)


mysql> show create table t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT '0',
  `b` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


此時master上t表的AUTO_INCREMENT值爲6。


假設數據已經同步到slave後,發生主從切換,會出現什麼情況?


a.先檢查新master上的數據是否已經同步過來
mysql> select *  from t;
+----+------+------+
| id | a    | b    |
+----+------+------+
|  1 |    1 |    1 |
|  2 |    2 |    2 |
|  5 |    3 |  300 |
+----+------+------+
3 rows in set (0.00 sec)


b.查看t表的表結構,發現AUTO_INCREMENT值爲4.與master不一致。
mysql> show create table t \G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT '0',
  `b` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


c.replace into 插入值
mysql> replace into t (a,b)values(8,8);
Query OK, 1 row affected (0.00 sec)


d.出現主鍵衝突

mysql> replace into t (a,b)values(9,9);
ERROR 1062 (23000): Duplicate entry '5' for key 'PRIMARY'


f.重試插入
mysql> replace into t (a,b)values(9,9);
Query OK, 1 row affected (0.01 sec)


mysql> show create table t \G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT '0',
  `b` int(11) DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `a` (`a`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


mysql> select *  from t;
+----+------+------+
| id | a    | b    |
+----+------+------+
|  1 |    1 |    1 |
|  2 |    2 |    2 |
|  4 |    8 |    8 |
|  5 |    3 |  300 |
|  6 |    9 |    9 |
+----+------+------+
5 rows in set (0.00 sec)



建議用ON DUPLICATE KEY UPDATE 的方式替換replace into。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章