lee 发表于 2020-9-14 22:06:45

深入MySQL--MySQL replace into导致的自增id问题

今天线上遇到一个问题,挺有意思,这里记录一下希望对大家有所帮助。某个表中,只有一条记录,发生高可用切换之后,自增id的值发生了变化,主从的自增id值不一致,导致数据写入报主键冲突的错误。

我们知道,在MySQL中,是支持replace语法的,当你执行replace into的时候,如果该条记录存在,那么replace会删除这条记录,然后重新insert一条新记录。这种操作在主从复制的场景下,可能会带来问题,这里我们简单模拟一下,建表语句如下:

CREATE TABLE `test1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uni_age` (`age`)
) ENGINE=InnoDBDEFAULT CHARSET=utf8

可以看到,表中的id是主键,age是唯一索引,我们先插入(2,2)和(3,3)两条数据。

然后,我们先来看主库上

mysql >>select * from test1;
+----+------+
| id | age|
+----+------+
|2 |    2 |
|3 |    3 |
+----+------+
2 rows in set (0.00 sec)

mysql >>replace into test1 values (6,3);
Query OK, 2 rows affected (0.00 sec)

mysql >>select * from test1;
+----+------+
| id | age|
+----+------+
|2 |    2 |
|6 |    3 |
+----+------+
2 rows in set (0.00 sec)

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

主库上进行replace之后,返回值是2 rows affected,其中之所以返回影响2行,是因为replace into的值是(6,3),而age=3这条记录已经存在,所以会先删除id=3,age=3这条记录,然后插入id=6,age=3这条记录,自增值变为7.

再来看从库上:
**** Hidden Message *****

末日流溢 发表于 2021-9-22 16:24:06

oooooooooooo好
页: [1]
查看完整版本: 深入MySQL--MySQL replace into导致的自增id问题