今天线上遇到一个问题,挺有意思,这里记录一下希望对大家有所帮助。某个表中,只有一条记录,发生高可用切换之后,自增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=InnoDB DEFAULT 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.
再来看从库上:
|
|