MySQL事务机制深度解析:从理论到实践(五)

本文全面解析MySQL数据库事务的核心机制,深入探讨事务的ACID特性、生命周期管理、隔离级别原理及InnoDB存储引擎的事务工作流程。涵盖事务的原子性、一致性、隔离性和持久性实现原理,详细分析不同事务隔离级别的应用场景和性能影响,并揭示InnoDB如何通过redo log、undo log、MVCC等机制保障事务的可靠执行。为数据库开发人员和管理员提供完整的事务理解和优化指导。

1.事务概念

  • 事务(Transaction)可以更通俗的理解为交易,所以事务会伴随着交易类的业务类型出现(工作模式);

  • 现实生活中存在很多的交易行为,比如:物换物的等价交换、货币换物的等价交换、虚拟货币换物(虚拟物品)的等价交换;

  • 因此就需要考虑如何保证现实生活中交易过程的和谐,一般会有法律、道德等方面规则进行约束;

  • 而在数据库服务中为了保证线上交易的"和谐",便加入了"事务"工作机制。

事务是数据库中处理交易类业务的核心机制,将一系列操作作为一个不可分割的工作单元。与现实生活中交易需要法律和道德约束类似,数据库事务通过ACID特性来保证数据操作的"和谐"与可靠。

2.事务特性

2.1 原子性(Atomicity)
  • 原子性表示一个事务生命周期中的DML语句,要么全成功要么全失败,不可以出现中间状态;

  • 语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;

  • 实现主要基于undo log

sh 复制代码
Begin:DML01 DML02 DML03 Commit;
2.2 一致性(Consistency)
  • 一致性表示一个事务发生前、中、后,数据都最终保持一致,即读和写都要保证一致性;
  • 事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障;
sh 复制代码
CR + Double write
2.3 隔离性(Isolation)
  • 隔离性表示一个事务操作数据行的时候,不会受到其他事务的影响,主要利用锁机制来保证隔离性;
2.4 持久性(Durability)

3.事务生命周期

  • 在运用事务机制完成相关工作任务时,对于事务使用是存在生命周期概念的,标准显示的事务生命周期控制语句有:
sh 复制代码
# 开启事务机制
begin;
start transaction;
# 提交事务任务
commit;
# 回滚事务操作
rollback;

说明:事务生命周期中,只能使用DML语句,其中包括:select、update、delete、insert;DDL语句会隐式进行提交

4.事务提交方式

4.1 自动提交方式(auto_commit)
sql 复制代码
mysql> select @@autocommit;
+--------------+
| @@autocommit |
+--------------+
|            1 |
+--------------+
1 row in set (0.00 sec)
-- 在事务自动提交功能设置修改时,设置为1表示开启自动提交,设置为0表示关闭自动提交

# 临时关闭事务自动提交功能
mysql> set global autocommit=0;
-- 配置调整后,重新登录mysql数据库生效

# 永久关闭事务自动提交功能
[root@db01 ~]# vim /etc/my.cnf
[mysqld]
autocommit=0
-- 配置调整后,重新启动mysql数据库生效

autocommit 开启与关闭优缺点

序号 参数配置 优势
情况01 autocommit=0 关闭事务自动提交 可以编写多个关联的DML,进行一次性提交操作,若出现异常可以回滚 符合原子特性
劣势
可能出现多个关联的DML,只是完成了部分操作,这时就可能等待状态 基于隔离特性,操作的数据表或数据行就会进入锁定状态
参数配置 优势
情况02 autocommit=1 开启事务自动提交 可以出现多个关联的DML,逐行操作自动提交,就可以不用处于锁等待状态
劣势
可能出现多个关联的DML,,每执行一条就进行提交,会造成多个语句执行不符合原子性
4.2 隐式提交方式

在进行事务操作时,需要注意操作语句必须都是DML语句,如果中间插入了DDL语句,也会造成之前的事务操作自动提交;

sql 复制代码
begin; DML1; DML2; DDL1; COMMIT; DML3; COMMIT;
-- 这种情况出现会破坏原本事务的原子性

隐式自动提交方式语句:

在出现隐式自动提交时,可能导致提交的非事务语句有:

序号 语句类型 涉及命令
01 DDL语句类型 alter、create、drop
02 DCL语句类型 grant、revoke、set password
03 锁定语句类型 lock tables、unlock tables
04 其他语句类型 truncate table、load data infile、select for update

说明:在多个数据库会话窗口中,A窗口的所有事务性DML操作,不会受到B窗口的非事务语句影响,同一会话窗口会有影响;

5.事务隔离级别

数据库事务隔离级别主要作用是实现事务工作期间,数据库操作读的隔离特性,所谓读的操作就是将数据页可以调取到内存;

然后可以读取数据页中相应数据行的能力,并且不同事务之间的数据页读操作相互隔离;

可以简单理解为:一个事务在对数据页中数据行做更新操作时,在没有更新提交前,另一个事务此时是不能读取数据页中数据行内容的;

对于数据库存储事务隔离级别包括4种,可以通过操作命令查看获取当前使用的隔离级别:

sql 复制代码
mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+
1 row in set (0.00 sec)

mysql> set global transaction_isolation='READ-UNCOMMITTED';

常用的事务隔离级别类型:

5.1 RU(READ-UNCOMMITTED 表示读未提交)

可以读取到事务未提交的数据,隔离性差,会出现脏读(当前内存读),不可重复读,幻读问题;

5.2 RC(READ-COMMITTED 表示读已提交)可用

可以读取到事务已提交的数据,隔离性一般,不会出现脏读问题,但是会出现不可重复读,幻读问题;

5.3 RR(REPEATABLE-READ 表示可重复读)默认

可以防止脏读(当前内存读),防止不可重复读问题,防止会出现的幻读问题,但是并发能力较差;

会使用next lock锁进制,来防止幻读问题,但是引入锁进制后,锁的代价会比较高,比较耗费CPU资源,占用系统性能;

5.4 SR(SERIALIZABLE 可串行化)

隔离性比较高,可以实现串行化读取数据,但是事务的并发度就没有了;

这是事务的最高级别,在每条读的数据上,加上锁,使之不可能相互冲突.

事务隔离级别官方链接:https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html

名词解读分析

  • 脏读:在一个事务窗口中,可以读取到别人没有提交的数据信息(可以看到内存中的数据);
  • 不可重复读:在一个事务中,利用相同的语句多次查询,获取的数据信息是不同的;

6.事务工作流程

根据存储事务的工作流程原理,来了解如何保证事务的ACID特性,利用了MySQL数据库的哪些工作机制;

名称解释:

sh 复制代码
1. redo log                          Disk   
 重做日志,当出现异常情况,内存中数据直接写入磁盘失败时,可以通过重启数据库服务,读取此文件修复数据信息;文件存储表项为:ib_logfile0~N    默认48M,轮询使用
 
2. redo log buffer                   mem
 重做日志生成缓冲区,相当于redo log的内存区域。redo log文件与redo log buffer是有IO关系的;
 事务修改提交后:redo log buffer -> redo log,表示写入数据到redo log;
 事务操作恢复时:redo log -> redo log buffer,表示读取数据从redo log;
 
3. tablespace file                   Disk          
 存储表数据行和索引等信息的文件,含有表空间所有数据文件;ibd
 
4. Innodb buffer pool                mem
 数据缓冲区,主要用于缓冲事务要处理的数据和索引信息,tablespace文件与buffer pool是有IO关系的;
 
5. LSN
 日志序列号,在buffer pool中有数据页信息的变化就会记录到redo log buffer中,主要记录变化了多少字节量;
 利用LSN记录相应数据页的日志变化量(LSN+变化字节量),也可以理解为记录的是日志量的变化;
 MySQL每次数据库启动,都会比较磁盘数据页和redolog的LSN,必须要求两者一致,数据库才能正常启动;
 
5. WAL(Write Ahead Log)
 redo日志生成记录优先于数据页写入到磁盘的过程,并且是支持预写入机制(group commit)的;
 
6. Dirty page
 表示在内存进行修改的数据页,在redo buffer中会记录数据页的数据量的变化,此时在数据页还未最终写入到磁盘中时,就称之为脏页,所以一般所谓的脏读就是读取脏页的数据页信息;
 
7. CheckPoint
 检查点,就是将脏页刷写到磁盘的动作;
 
8. DB_TRX_ID(6字节)
 事务ID号,InnoDB会为每一个事务生成一个事务号(由事务管理器管理TM),伴随着整个事务生命周期其中事务ID号码信息,在redo和undo日志文件中都会有相应的标识;
9. DB_ROLL_PTR(7字节)
 回滚指针,在rollback时会使用undo日志回滚已修改的数据,DB_ROLL_PTR会指向此次事务的回滚业务点;从而找到undo上的相应的日志信息;
 数据库名词解释官方参考:https://dev.mysql.com/doc/refman/8.0/en/glossary.html

工作流程:

sh 复制代码
1. redo保证了ACID中的D特性,另外A C也有间接关联;
说明:利用redo Log重做日志功能可以保证事务的D特性,基于可以丢内存数据,但是不可以丢操作事务日志的原则;
2. undo保证了ACID中的A特性,同时C和I的特性也有关系;
说明:利用undo Log重做日志功能可以保证事务的A特性,基于先进行数据页前滚操作恢复脏页,在进行回滚操作恢复操作前事务;
3. cr+dw保证了ACID中的C特性
InnoDB crash recovery:数据库意外宕机时刻,通过redo前滚+undo回滚保证数据的最终一致;
InnoDB doubewrite buffer:早期默认存储在ibdataN中,解决数据页写入不完整;DWB一共2M,分两次。每次1M写入;
4. 事务中的I特性如何保证  保证读写隔离性
主要对数据库服务并发访问资源的保护,在并发事务工作期间,防止事务与事务之间的资源争抢(相互影响);
  利用MVCC机制隔离(只能保证读的隔离)
  利用隔离级别和锁机制保证写的隔离

7.总结

​ 事务机制是数据库系统的基石,InnoDB通过精心设计的Redo Log、Undo Log、MVCC和锁机制,实现了完整的ACID特性保障。深入理解事务的工作原理,对于设计高性能、高可靠的数据库应用至关重要。

​ 通过合理配置事务参数、选择适当的隔离级别、优化事务设计,可以在保证数据一致性的同时,最大限度地提升系统并发性能。掌握事务机制不仅有助于日常开发,更是进行数据库性能调优和故障排查的基础技能。

​ 在分布式系统和云原生架构日益普及的今天,事务机制的理解和运用显得更加重要,它是构建可靠数据服务的关键技术保障。

相关推荐
剩下了什么4 小时前
MySQL JSON_SET() 函数
数据库·mysql·json
山峰哥5 小时前
数据库工程与SQL调优——从索引策略到查询优化的深度实践
数据库·sql·性能优化·编辑器
较劲男子汉5 小时前
CANN Runtime零拷贝传输技术源码实战 彻底打通Host与Device的数据传输壁垒
运维·服务器·数据库·cann
java搬砖工-苤-初心不变5 小时前
MySQL 主从复制配置完全指南:从原理到实践
数据库·mysql
WangYaolove13147 小时前
基于python的在线水果销售系统(源码+文档)
python·mysql·django·毕业设计·源码
山岚的运维笔记7 小时前
SQL Server笔记 -- 第18章:Views
数据库·笔记·sql·microsoft·sqlserver
roman_日积跬步-终至千里8 小时前
【LangGraph4j】LangGraph4j 核心概念与图编排原理
java·服务器·数据库
汇智信科8 小时前
打破信息孤岛,重构企业效率:汇智信科企业信息系统一体化运营平台
数据库·重构
野犬寒鸦8 小时前
从零起步学习并发编程 || 第六章:ReentrantLock与synchronized 的辨析及运用
java·服务器·数据库·后端·学习·算法
霖霖总总8 小时前
[小技巧66]当自增主键耗尽:MySQL 主键溢出问题深度解析与雪花算法替代方案
mysql·算法