mysql主从配置自增id_MySQL自增列主从不一致的测试(r12笔记第37天)

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

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

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

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.

[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

mysql> delete from t1 where id=3;

Query OK, 1 row affected (0.02 sec)这个时候会发现AUTO_INCREMENT=4的值不会有任何变化。

我们来挖掘一下binlog的内容,就会发现insert语句很特别。

# /usr/local/mysql_5.7.17/bin/mysqlbinlog --socket=/home/data/s1/s1.sock --port=24801 -vv  /home/data/s1/binlog.000001可以看到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中修复。让我们拭目以待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值