自增不再简单:深入探索MySQL自增ID的持久化之道

概述

MySQL中的自增特性估计大家或多或少都是用过。一张表中只能由一个自增字段,通常我们会把它设置为主键,但是随着大家系统越来越分布式,为了一些性能和可扩展性问题,大家目前选择更多的都是分布式ID(雪花算法、UUID,Redis ID, Leaf)。

但是我觉得还是有必要谈一下自增变量为什么要持久化,或许可以为大家以后设计一些系统作为参考。

自增使用

我们先来看看MySQL自增的使用,自增可以在CREATE TABLE和ALTER TABLE使用:

  1. 建表时指定自增
  2. 修改列为自增

建表时指定自增

建表时指定自增列:


create table trade_user(id int not null auto_increment primary key,name varchar(20) not null default '' comment 'name'
)comment='trade user';

COPY

file

修改列为自增


create table trade_user1(id int not null primary key,name varchar(20) not null default '' comment 'name'
)comment='trade user';ALTER TABLE trade_user1 modify id INT NOT NULL auto_increment;

COPY

file

自增模式

表中的自增列有一个专用的锁:AUTO-INC锁,这个锁保证并发场景下没有问题。

AUTO-INC锁,这个锁有几种模式,MySQL 8默认的模式为交错模式,我们来查看下MySQL 8默认的锁模式:


SHOW VARIABLES LIKE 'innodb_autoinc_lock_mode';

COPY

file

我们看到Value为2,2是什么?来查个表:

自增锁模式备注
0“传统”模式为每个语句获取表级自增锁,并在语句结束时释放。
1“连续”模式在查询执行的第一次自增ID的生成时获取表级自增锁,并在语句结束时释放。多个并发的自增语句可以同时获取ID并执行。
2“交错”模式只在自增ID需要的时候获取行级的自增锁。这种方式可以大大降低锁的竞争,提高并发性能,但可能会因事务的回滚导致自增ID的不连续。

默认模式

MySQL版本默认值自增锁模式
5.10“传统”模式
5.1 – 5.71“连续”模式
8.02“交错”模式

自增问题

交错自增锁的问题是什么?我们来看看官方的解释:

The default setting is 2 (interleaved) as of MySQL 8.0, and 1 (consecutive) before that. The change to interleaved lock mode as the default setting reflects the change from statement-based to row-based replication as the default replication type, which occurred in MySQL 5.7. Statement-based replication requires the consecutive auto-increment lock mode to ensure that auto-increment values are assigned in a predictable and repeatable order for a given sequence of SQL statements, whereas row-based replication is not sensitive to the execution order of SQL statements.

持久化

遇到了什么问题需要持久化?我们来看个MySQL的bug,bug链接:MySQL Bugs: #199: Innodb autoincrement stats los on restart
这个bug大概描述了MySQL交错模式自增导致的问题,复现步骤:

  1. 创建一个名为“a”的表,其id字段设置为自增字段。
  2. 向表中插入三条记录,到此为止,生成的id值分别为1, 2, 3。
  3. 删除id=3的记录,在表中再次插入一条记录,新记录的id值为4,因此当前表中的id值为1, 2, 4。
  4. 删除id=4的记录,此时MySQL服务器重启。
  5. 重启后,向表中再次插入一条记录,新插入的记录的id值变为了3,这就是AUTO_INCREMENT字段生成重复值的情况。

根据描述,这个问题可能导致的问题是复制中断,因为在主从复制中,主库和从库的AUTO_INCREMENT值可能会不同,从而导致主从数据不一致。

没有持久化自增值之前怎么得到自增值

这个我们自己思考下就可以想到:首先自增变量肯定要放到内存里面,并且与表有一一对应关系,然后自增变量要存储到某个地方以便下次服务启动时读取。

MySQL的思路基本和上面差不多,MySQL的自增变量恢复遵循以下步骤:

  1. 首先,表的自增值肯定是要放到内存中的
  2. 其次, 我们需要思考哪儿有这个自增值:就是表字段
  3. 然后,MySQL通过查询表的元数据来定位和获取自增字段的最大值。
  4. 最后,MySQL执行一条SQL就可以获取了

SELECT MAX(auto_increment_column) FROM table

COPY

例如,要查询’trade_user’表中’id’字段的最大值,可以使用以下SQL:


select max(id) from trade_user

COPY

持久化之后自增ID放到哪儿了?

放到了information_schema数据字典中了,如果你要查询你表的当前的自增ID值,执行下面这条SQL:


SELECT `AUTO_INCREMENT`
FROM `information_schema`.`tables`
WHERE `table_schema` = 'blog'
AND `table_name` = 'trade_user1';

COPY

file

再进一步,到底怎么存储的

先看MySQL官方怎么说:

In MySQL 8.0, this behavior is changed. The current maximum auto-increment counter value is written to the redo log each time it changes and saved to the data dictionary on each checkpoint. These changes make the current maximum auto-increment counter value persistent across server restarts.

这个大概意思就是:
MySQL会把自增计数器的当前最大值写入redo log,并在每次检查点时保存到数据字典中,这样就完成了自增计数器的持久化。

数据库重启了以后怎么恢复?因为重启可能是因为崩溃,最新的自增值还没有写入到数据字典中,那么就得这么干了:

  1. 数据库启动的时候先从数据字典中获取元数据,把表的自增ID加载到内存中
  2. 服务器重放redo log中的所有事务,然后把自增ID修改为redo log中的值

总结

从MySQL自增值持久化问题以及解决方案,我们从中可以学习到:

  1. 数据持久化和一致性的重要性
  2. 设计系统时要考虑到异常情况,如果没有考虑到异常情况,出一些意料之外的问题你会很蒙蔽
  3. 全局唯一ID的重要性,这个ID非常重要,要是混乱了,你的饭碗可能瞬间都没了,而且后面的就刷库吧

参考

1. MySQL自增变量持久化 – FOF编程网

创作不易,难免会有点错误或者可读性问题,请大家理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/772104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【python】Jupyter Notebook 修改默认路径

文章目录 一、修改前(一)问题(二)修改前的默认路径 二、修改配置文件、更改路径(一)找到配置文件并打开(二)创建目标文件夹、得到新的路径(三)修改配置文件 三…

大模型时代的向量数据库:原理解析和应用案例

大家好,在人工智能领域,数据处理和加工的需求愈发增加。随着人们深入探索AI高级的应用,如图像识别、语音搜索和推荐引擎等,数据的复杂性也在不断地增加。此时传统的数据库存储方式已不能完全满足需求,向量数据库应运而…

su怎么做展厅模型---模大狮模型网

要在SketchUp中创建展厅模型,你可以按照以下基本步骤进行: 绘制基本结构: 使用SketchUp的绘图工具(线条、矩形、圆形等)来创建展厅的基本结构,包括墙壁、地板和天花板等。确保按照实际尺寸和比例进行绘制。 添加家具和展品&…

【C++教程从0到1入门编程】第十三篇:STL中list类的模拟实现

一、list的模拟实现 #include<iostream> #include<assert.h> #pragma once namespace jyr {template<class T>struct _list_node{_list_node<T>* _next;_list_node<T>* _prev;T _data;_list_node(const T& val T()):_next(nullptr), _prev(…

Zabbix 配置使用

目录 配置流程 添加组机组 添加模板 添加主机 配置图形 配置大屏 Monitoring 配置地图 最新数据 故障 使用IT服务 使用报表 资产管理 全局搜索 导入导出 用户权限 用户组权限 用户 匿名用户 调试模式 与 LDAP 对接 维护模式 故障确认 批量更新 配置流程…

【办公类-21-10】三级育婴师 视频转文字docx(等线小五单倍行距),批量改成“宋体小四、1.5倍行距、蓝色字体、去掉五分钟”

作品展示 背景需求 今天将最后3个育婴师操作视频做整理 第1步&#xff1a;视频MP4转MP3 【办公类-40-01】20240311 用Python将MP4转MP3提取音频 &#xff08;家长会系列一&#xff09;-CSDN博客文章浏览阅读393次&#xff0c;点赞9次&#xff0c;收藏6次。【办公类-40-01】20…

[项目前置]websocket协议

websocket协议介绍 WebSocket 协议是一种在单个 TCP 连接上进行全双工通讯的协议。 WebSocket 使得客户端和服务器之间的数据交换变得更简单&#xff0c;允许服务器主动向客户端推送数据。它在 2011 年成为国际标准&#xff0c;现在被所有现代浏览器支持。WebSocket 设计用于…

iNet Network Scanner Mac 网络扫描工具

iNet Network Scanner for Mac是一款功能强大的网络扫描工具&#xff0c;专为Mac用户设计。它提供了全面而深入的网络分析功能&#xff0c;使用户能够轻松获取Mac连接的网络和设备的详细信息。 软件下载&#xff1a;iNet Network Scanner Mac v3.1.0激活版 这款软件具备多种扫描…

业务服务:xss攻击

文章目录 前言一、使用注解预防1. 添加依赖2. 自定义注解3. 自定义校验逻辑4. 使用 二、使用过滤器1. 添加配置2. 创建配置类3. 创建过滤器4. 创建过滤器类5. 使用 前言 xss攻击时安全领域中非常常见的一种方法&#xff0c;保证我们的系统安全是非常重要的 xss攻击简单来说就…

TCP(socket 套接字)编程 1

一、TCP套接字编程架构如下 二、相关代码实现 1、服务器端代码 package com.company;import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket;public class Main {public static void main(String[] args) {…

javaWeb健身房管理系统

一、简介 随着人们健康意识的增强和生活水平的提高&#xff0c;健身已经成为了现代人生活中不可或缺的一部分。为了更好地管理健身房的日常运营&#xff0c;我们设计并开发了一款基于 JavaWeb 的健身房管理系统。本系统采用了最新的技术&#xff0c;包括 Spring Boot、MyBatis…

nacos集群搭建实战

集群结构图 初始化数据库 Nacos默认数据存储在内嵌数据库Derby中&#xff0c;不属于生产可用的数据库。官方推荐的使用mysql数据库&#xff0c;推荐使用数据库集群或者高可用数据库。 首先新建一个数据库&#xff0c;命名为nacos&#xff0c;而后导入下面的SQL&#xff08;直…

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示(PC端、手机端、平板端)

智慧工地源码 数字孪生可视化大屏 工地管理平台系统源码 多端展示&#xff08;PC端、手机端、平板端&#xff09; 智慧工地系统多端展示&#xff08;PC端、手机端、平板端&#xff09;;数字孪生可视化大屏&#xff0c;一张图掌握项目整体情况;使用轻量化模型&#xff0c;部署三…

ubuntu22.04配置Azure Kinect DK深度相机

一.安装SDK 今天我来配置一下微软公司的Azure Kinect DK深度相机,以前在ubuntu18.04上配置过,因为官方说唯一支持linux版本是18.04,所以在18.04中配置还算顺利 but这不代表不可以在更高版本的ubuntu中使用,只不过需要自己去多配置一些东西 apt 源安装 更新源: c…

25.7 MySQL 数据库和表的基本操作

1. 基础知识 1.1 一条数据的存储过程 存储数据确实是处理数据的基石, 只有确保数据被准确无误且有条理地存储, 我们才能对其进行深入的处理和细致的分析. 否则, 这些数据就像是一团毫无章法的乱麻, 让我们难以捉摸其内在的逻辑和价值.那么, 如何才能够将用户那些与经营紧密相关…

VITIS更新硬件平台

VITIS硬件平台更新以后如何重新导入 在之前建立的硬件平台上右击&#xff0c;选择Update Hardware Specification&#xff0c;选择最新导出的硬件平台文件&#xff1b; 重建板级支持包 选择复位重建BSP源文件&#xff0c;俩个地方的BSP都Reset一下&#xff0c;然后Build&…

Transformer的前世今生 day08(Positional Encoding)

前情提要 Attention的优点&#xff1a;解决了长序列依赖问题&#xff0c;可以并行。Attention的缺点&#xff1a;开销变大了&#xff0c;而且不存在位置关系为了解决Attention中不存在位置关系的缺点&#xff0c;我们通过位置编码的形式加上位置关系 Positional Encoding&…

LinkedIn账号为什么被封?被封后如何解决?

近期会有一些小伙伴说自己遇到了帐号无法登录的情况&#xff0c;其实出现领英帐号被封号(被限制登录)主要会有两类情况&#xff0c;今天就给大家分享一下如果被封该如何解决&#xff0c;强烈建议收藏。 在电脑领英官网或者手机领英APP上&#xff0c;输入领英帐号密码点击登录后…

HCIP的学习(4)

GRE和MGRE VPN---虚拟专用网络。指依靠ISP&#xff08;运营商&#xff09;或其他公有网络基础设施上构建的专用的安全数据通信网络。该网络是属于逻辑上的。​ 核心机制—隧道机制&#xff08;封装技术&#xff09; GRE—通用路由封装 ​ 三层隧道技术&#xff0c;并且是属于…

代码随想录 图论

目录 797.所有可能得路径 200.岛屿数量 695.岛屿的最大面积 1020.飞地的数量 130.被围绕的区域 417.太平洋大西洋水流问题 827.最大人工岛 127.单词接龙 841.钥匙和房间 463.岛屿的周长 797.所有可能得路径 797. 所有可能的路径 中等 给你一个有 n 个节点的…