MySQL--事务

目录

[一、事务 Transaction](#一、事务 Transaction)

1.事务的ACID四项特性

2.事务生命周期

1)标准事务控制语句

2)标准的事务语句

3)事务操作演示​编辑

4)自动提交机制

5)隐式提交的特殊情况

6)触发隐式回滚的特殊情况

二、事务的ACID如何保证

[1.redo log 保障持久性,对于原子性和一致性也有保障](#1.redo log 保障持久性,对于原子性和一致性也有保障)

[2.Undo 保障原子性,对于一致性和隔离性也有保障](#2.Undo 保障原子性,对于一致性和隔离性也有保障)

[3.Double Write 机制](#3.Double Write 机制)

4.ACSR自动故障恢复实现

5.隔离级别保障隔离性

6.MVCC多版本并发控制--事务快照


一、事务 Transaction

1.事务的ACID四项特性

|---------------|-----|-----------------------------------------------------|
| A:atemicity | 原子性 | 事务中的所有操作,都是一个完整的整体,要么全成功,要么全失败,没有中间状态 |
| C:consistency | 一致性 | 事务发生在前、中、后阶段,数据应当保证一致性状态,数据不会受到任何破坏,事务最终一致是事务的最根本目的 |
| I:isolation | 隔离性 | 多事务工作期间互相不影响 |
| D:durability | 持久性 | 数据保证永远不丢失,数据落盘 |

2.事务生命周期

1)标准事务控制语句

begin/start transaction 开启事务

commit 提交事务

rollback 回滚事务

2)标准的事务语句

DML语句:update、delete、insert、select

3)事务操作演示
4)自动提交机制

select @@autocommit;

作用:在没有使用begin时显示触发DML操作,mysql会在此条命令执行完成后自动提交事务

一般是关闭掉的(设为0),不然自动提交后不能回滚

如何配置:vim /etc/my.cnf -->autocommit=0 重启生效

5)隐式提交的特殊情况

1)begin

a......

b......

begin(第二次begin时会触发隐式提交)

2)begin

set......(set命令会触发隐式提交)

3)DDL语句:alter、create、drop

4)DCL语句:GRANT/REVOKE/SET PASSWORD

5)锁定语法:LOCK TABLES 和 UNLOCK TABLES

6)TRUNCATE TABLE

6)触发隐式回滚的特殊情况

中间命令执行失败

会话结束:窗口关闭,kill...

数据库停止

二、事务的ACID如何保证

事务相关的关键名词解释
redo log 重做日志 磁盘文件:ib_logfile
redo log 重做日志 内存缓冲区:redo log buffer
数据表空间 存放数据和索引 磁盘区:ibd
数据表空间 存放数据和索引 内存缓冲区:buffer_pool
LSN 日志序列号 mysql每次数据库启动,都会比较磁盘数据页和redo log的LSN,必须要求两者LSN一致数据库才能启动
WAL 日志优先写入 redo优先于数据写入磁盘,redo没写完,数据页不可能开始写
dirty page 脏页 内存脏页,内存中发生了修改,没写入到磁盘之前,被弄脏的数据页
CKPT checkpoint mysql维护着检查点队列(checkpoint list),检查点就是将脏页刷写到磁盘
DB_TRX_ID 事务号 InnoDB会为每一个事务生成一个事务号,伴随着整个事务生命周期
DB_ROLL_PTR 回滚指针 回滚信息的位置点

1.redo log 保障持久性,对于原子性和一致性也有保障

1)作用

重做日志

记录数据变化

记录LSN变化

记录UNDO信息,Trx_id,roll_ptr

记录有无commit_mark

2)刷新机制

事务提交时刷新:innodb_flush_log_at_trx_commit=1

成组提交:group commit


2.Undo 保障原子性,对于一致性和隔离性也有保障

1)作用

实现回滚的功能,也是MVCC特性的主要保障

undo是优先于redo记录信息的,所以能回滚


3.Double Write 机制

在buffer pool写入磁盘时,防止数据页出现部分写,则会把数据先写入double write文件中,再写入磁盘

double write文件一共2m,满了则会覆盖

只在系统宕机,出现部分写的时候会用到DW


4.ACSR自动故障恢复实现

例如:begin;

update set a=1 -->a=2;

未提交;

1)发起更新语句,从磁盘将t1.ibd,page_no=1001数据页,LSN=100,加载到buffer pool中

2)更新buffer pool中数据页之前,首先申请undo slot

3)生成当前事务DB_TRX_ID(6字节的事务号)和DB+ROLL+PTR(7字节的回滚指针)

4)开始修改内存buffer pool中的数据页的值,并更新LSN=101

5)在redo buffer中记录内存数据页修改的过程日志和LSN=101

6)如果此次事务的日志,随着其他的日志提交,则redo buffer中的日志刷写道redo log中

而假设在此时出现宕机,下次启动时,InnoDB的ACSR机制会自动进行故障恢复:

7)启动数据库引擎

8)InnoDB自动检查磁盘数据页ibd文件和redo log文件的LSN大小

9)如果发现--> redo log的LSN > ibd的LSN,则立即触发故障恢复机制

10)前滚:加载磁盘数据页和redo log到内存,通过redo buffer重做事务,构造脏页

11)回滚:检查到此次事务并没有commit标记,则触发回滚操作

12)此时,根据DB_TRX_ID(6字节的事务号)和DB+ROLL+PTR(7字节的回滚指针),从undo的segment的slot中找到此次事务的undo日志,进行回滚

13)所有工作做完,数据库实例正常启动,数据恢复到a=1的状态


5.隔离级别保障隔离性

1)作用

隔离级别 transaction_isolation,提供了读的隔离性,select、update、delete、insert都牵扯到读数据页

2)隔离级别的四种类型

名词解释:

脏读现象:事务工作期间,读到了别的事务正在发生修改的脏页

不可重复读:在同一个事务窗口,做相同数据的读取,得到的是不同的值

幻读:在事务更新的过程中,出现了其他事务已经提交的数据的幻行

|--------------|------|-------------|
| RU | 读未提交 | 脏读、不可重复读、幻读 |
| RC | 读已提交 | 不可重复读、幻读 |
| RR(默认级别) | 可重复读 | 幻读 |
| SR | 可串行化 | 可串行化 |

3)隔离级别设置

select @@transaction_isolation;默认是RR


6.MVCC多版本并发控制--事务快照

每次开启一个全新的事务窗口(begin),都会生成当前最新的事务快照,此次事务会在此次快照中进行操作,直到事务commit或rollback

这种技术也称为一致性快照读取,可以很大程度上提高事务的并发能力,防止RR级别下的不可重复读现象

相关推荐
RestCloud21 分钟前
为什么说零代码 ETL 是未来趋势?
数据库·api
浮游本尊1 小时前
Java学习第22天 - 云原生与容器化
java
ClouGence2 小时前
CloudCanal + Paimon + SelectDB 从 0 到 1 构建实时湖仓
数据库
渣哥3 小时前
原来 Java 里线程安全集合有这么多种
java
间彧3 小时前
Spring Boot集成Spring Security完整指南
java
间彧3 小时前
Spring Secutiy基本原理及工作流程
java
Java水解4 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
Java水解4 小时前
Mysql查看执行计划、explain关键字详解(超详细)
后端·mysql
洛小豆6 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学7 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端