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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:     MySQL里面有一个问题尤其值得注意,那就是自增列的重复值问题,之前也简单分析过一篇,但是在后续我想了下,还有很多地方需要解释,一个就是从库的自增列是如何维护的,是否重启从库,自增列会受到影响。

    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中修复。让我们拭目以待。



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
关系型数据库 MySQL 测试技术
【赵渝强老师】MySQL的基准测试与sysbench
本文介绍了MySQL数据库的基准测试及其重要性,并详细讲解了如何使用sysbench工具进行测试。内容涵盖sysbench的安装、基本使用方法,以及具体测试MySQL数据库的步骤,包括创建测试数据库、准备测试数据、执行测试和清理测试数据。通过这些步骤,可以帮助读者掌握如何有效地评估MySQL数据库的性能。
|
2月前
|
机器学习/深度学习 JSON 算法
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-Seg模型进行图像分割的完整流程,包括图像分割的基础知识、YOLOv5-Seg模型的特点、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。通过实例代码,指导读者从自定义数据集开始,直至模型的测试验证,适合深度学习领域的研究者和开发者参考。
775 3
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
|
2月前
|
测试技术
自动化测试项目实战笔记(三):测试用户注册(验证码错误,成功,出现弹框时处理)
本文是关于自动化测试项目实战笔记,主要介绍了如何测试用户注册功能,包括验证码错误、注册成功以及弹框处理的测试步骤和代码实现。
110 2
自动化测试项目实战笔记(三):测试用户注册(验证码错误,成功,出现弹框时处理)
|
2月前
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
119 1
|
2月前
|
JSON 算法 数据可视化
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
这篇文章是关于如何通过算法接口返回的目标检测结果来计算性能指标的笔记。它涵盖了任务描述、指标分析(包括TP、FP、FN、TN、精准率和召回率),接口处理,数据集处理,以及如何使用实用工具进行文件操作和数据可视化。文章还提供了一些Python代码示例,用于处理图像文件、转换数据格式以及计算目标检测的性能指标。
73 0
测试专项笔记(一): 通过算法能力接口返回的检测结果完成相关指标的计算(目标检测)
|
2月前
|
机器学习/深度学习 并行计算 数据可视化
目标分类笔记(二): 利用PaddleClas的框架来完成多标签分类任务(从数据准备到训练测试部署的完整流程)
这篇文章介绍了如何使用PaddleClas框架完成多标签分类任务,包括数据准备、环境搭建、模型训练、预测、评估等完整流程。
134 0
目标分类笔记(二): 利用PaddleClas的框架来完成多标签分类任务(从数据准备到训练测试部署的完整流程)
|
2月前
|
机器学习/深度学习 JSON 算法
语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
本文介绍了DeepLab V3在语义分割中的应用,包括数据集准备、模型训练、测试和评估,提供了代码和资源链接。
275 0
语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
|
2月前
|
机器学习/深度学习 数据采集 算法
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
这篇博客文章介绍了如何使用包含多个网络和多种训练策略的框架来完成多目标分类任务,涵盖了从数据准备到训练、测试和部署的完整流程,并提供了相关代码和配置文件。
62 0
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
|
2月前
|
测试技术 数据安全/隐私保护 Python
自动化测试项目实战笔记(四):测试用户登录(账号密码错误,成功,出现弹框等情况)
本文介绍了使用Selenium进行自动化测试时如何测试用户登录的不同情况,包括账号密码错误、登录成功以及处理登录时出现的弹框,并提供了相应的Python代码实现。
79 0
自动化测试项目实战笔记(四):测试用户登录(账号密码错误,成功,出现弹框等情况)
|
1月前
|
JSON Java 测试技术
SpringCloud2023实战之接口服务测试工具SpringBootTest
SpringBootTest同时集成了JUnit Jupiter、AssertJ、Hamcrest测试辅助库,使得更容易编写但愿测试代码。
60 3