前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL自增列主从不一致的测试(r12笔记第37天)

MySQL自增列主从不一致的测试(r12笔记第37天)

作者头像
jeanron100
发布2018-03-21 15:50:10
1K0
发布2018-03-21 15:50:10
举报
文章被收录于专栏:杨建荣的学习笔记

MySQL里面有一个问题尤其值得注意,那就是自增列的重复值问题,之前也简单分析过一篇MySQL自增列的重复值问题(r12笔记第25天),但是在后续我想了下,还有很多地方需要解释,一个就是从库的自增列是如何维护的,是否重启从库,自增列会受到影响。

我们继续来测试一下。首先复现这个问题。

创建表t1,插入3行数据。

代码语言:javascript
复制
use test;
[test]> drop table if exists t1;
Query OK, 0 rows affected, 1 warning (0.01 sec)
> create table t1(id int auto_increment, a int, primary key (id)) engine=innodb;
Query OK, 0 rows affected (0.02 sec)
insert into t1 values (1,2);
insert into t1 values (null,2);
insert into t1 values (null,2);
[test]> select *from t1;               
+----+------+
| id | a    |
+----+------+
|  1 |    2 |
|  2 |    2 |
|  3 |    2 |
+----+------+

因为存在3行数据,这个时候自增列的值是4.

代码语言:javascript
复制
[test]> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

我们删除id值最大的记录id=3

代码语言:javascript
复制
mysql> delete from t1 where id=3;
Query OK, 1 row affected (0.02 sec)

这个时候会发现AUTO_INCREMENT=4的值不会有任何变化。 我们来挖掘一下binlog的内容,就会发现insert语句很特别。

代码语言:javascript
复制
# /usr/local/mysql_5.7.17/bin/mysqlbinlog --socket=/home/data/s1/s1.sock --port=24801 -vv  /home/data/s1/binlog.000001
代码语言:javascript
复制
可以看到insert语句是MySQL独有的语法形式。
### SET
###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
###   @2=2 /* INT meta=0 nullable=1 is_null=0 */
# at 2271

delete也会基于行级变更,定位到具体的记录的方式来删除。

### DELETE FROM `test`.`t1` ### WHERE ### @1=3 /* INT meta=0 nullable=0 is_null=0 */ ### @2=2 /* INT meta=0 nullable=1 is_null=0 */ # at 2509 我们重启一下数据库。

# mysqladmin --socket=/home/data/s1/s1.sock --port=24801 shutdown # /bin/sh /usr/local/mysql_5.7.17/bin/mysqld_safe --defaults-file=/home/data/s1/s1.cnf &

重启之后就会发现情况发生了变化,原来的自增值4现在变为了3,这个也是基于max(id)+1的方式来计算的。

mysql> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)

这个时候我们来关注一下从库,从库的自增列值会变化吗? mysql> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 1 row in set (0.00 sec)

这个时候就会发现重启数据库以后,主从的自增列的值不同了。 那么我们来进一步测试,在主库插入一条记录,这样自增列的值就是4.

mysql> insert into t1 values (null,2); Query OK, 1 row affected (0.01 sec)

自增列的值为4,而从库的自增列的值依旧没有任何变化。

继续插入一条记录,这个时候主库的自增列就会是5

mysql> insert into t1 values (null,2); Query OK, 1 row affected (0.00 sec)

而从库呢,这个时候自增列会持续发生变化吗?我们来验证一下,这个时候从库的自增列又开始生效了。

mysql> show create table t1\G *************************** 1. row *************************** Table: t1 Create Table: CREATE TABLE `t1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) 还有一点需要注意,那就是指定了自增列的值,这一点上和Oracle有一定的差距,但是又很相似。 这个时候数据库主库中的数据如下:

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

为了方便测试,我们继续插入一条数据,这一次我指定了id值。

mysql> insert into t1 values(6,2); Query OK, 1 row affected (0.00 sec)

让人感到安慰的是,这张情况下自增列还是会持续增加。

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

此时查看从库,这个自增列也还是7,, 通过这个案例,我们能够看到在MySQL会存在这样一类问题,实际上在多环境历史数据归档的情况下,如果主库重启,很可能会出现数据不一致的情况。

我也在MySQL的官方bug列表中看到很多人在讨论这个问题,看来很多人碰到这个坑。而这个问题其实细究起来实现也不是一个很繁琐的工作,为什么一直没有修复。

这个问题在MySQL很久以前就有,在现在依旧存在,什么时候会修复呢,根据官方的计划会在8.0中修复。让我们拭目以待。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档