事务运行模式(3种)

自动提交事务:默认事务管理模式。隐式开启,隐式提交.如果一个语句成功地完成,则提交该语句;如果遇到错误,则回滚该语句。
显式事务:以BEGIN TRANSACTION显式开始,以COMMIT或ROLLBACK显式结束。
隐性事务:隐式开启,显式提交,关掉自动提交即可.当连接以此模式进行操作时,sql将在提交或回滚当前事务后自动启动新事务。无须描述事务的开始,只需提交或回滚每个事务。它生成连续的事务链。

一旦执行commit或者rollback,事务就结束了

标准的事务控制语句

(1) 如何开启事务

begin ;

(2) 标准的事务语句

DML :

insert

update

delete

(3)事务的结束

提交:

commit;

回滚:

rollback;

自动提交机制(autocommit)

select @@autocommit;

在线(即在登陆状态下)修改参数:

(1) 会话级别:

mysql> set autocommit=0;

即时生效,只影响当前登录会话

(2)全局级别:

mysql> set global autocommit=0;

断开窗口重连后生效,影响到所有新开的会话

(3)永久修改(重启生效)

vim /etc/my.cnf

autocommit=0

隐式提交的情况

触发隐式提交的语句:

begin

a

b

create database

导致隐式提交的非事务语句:

DDL语句: (ALTER、CREATE 和 DROP)

DCL语句: (GRANT、REVOKE 和 SET PASSWORD)

锁定语句:(LOCK TABLES 和 UNLOCK TABLES)

导致隐式提交的语句示例:

TRUNCATE TABLE

LOAD DATA INFILE

SELECT FOR UPDATE

10.2 事务的ACID如何保证?

10.2.1 一些概念名词
redo log : 重做日志,对应的磁盘文件:ib_logfile0~1 ,默认50M , 轮询使用

redo log buffer :redo内存区域

ibd文件 : 存储 数据行和索引

data buffer pool : 缓冲区池,数据和索引的缓冲

LSN : 日志序列号
ibd ,redolog ,data buffer pool, redo buffer
MySQL 每次数据库启动,都会比较磁盘数据页和redolog的LSN,必须要求两者LSN一致数据库才能正常启动

WAL (持久化):
write ahead log 日志优先写的方式实现持久化,日志是优先于数据写入磁盘的

脏页 : 内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.
CKPT : Checkpoint,检查点,就是将脏页刷写到磁盘的动作

TXID: 事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务.

10.2.2 事务日志-- redo 重做日志
作用?
主要功能 保证 "D" , A C 也有一定的作用
(1)记录了内存数据页的变化.
(2)提供快速的持久化功能(WAL)
(3)CSR(crash recovery自动故障恢复)过程中实现前滚的操作(磁盘数据页和redo日志LSN一致)

redo日志位置
redo的日志文件:iblogfile0 iblogfile1

redo buffer:数据页的变化信息+数据页当时的LSN号

redo的刷写策略

commit;
刷写当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘
MySQL : 在启动时,必须保证redo日志文件和数据文件LSN必须一致, 如果不一致就会触发CSR,最终保证一致

10.2 事务的ACID如何保证?

10.2.1 一些概念名词
redo log : 重做日志,对应的磁盘文件:ib_logfile0~1 ,默认50M , 轮询使用

redo log buffer :redo内存区域

ibd文件 : 存储 数据行和索引

data buffer pool : 缓冲区池,数据和索引的缓冲

LSN : 日志序列号
ibd ,redolog ,data buffer pool, redo buffer
MySQL 每次数据库启动,都会比较磁盘数据页和redolog的LSN,必须要求两者LSN一致数据库才能正常启动

WAL (持久化):
write ahead log 日志优先写的方式实现持久化,日志是优先于数据写入磁盘的

脏页 : 内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.
CKPT : Checkpoint,检查点,就是将脏页刷写到磁盘的动作

TXID: 事务号,InnoDB会为每一个事务生成一个事务号,伴随着整个事务.

10.2.2 事务日志-- redo 重做日志
作用?
主要功能 保证 "D" , A C 也有一定的作用
(1)记录了内存数据页的变化.
(2)提供快速的持久化功能(WAL)
(3)CSR(crash recovery自动故障恢复)过程中实现前滚的操作(磁盘数据页和redo日志LSN一致)

redo日志位置
redo的日志文件:iblogfile0 iblogfile1

redo buffer:数据页的变化信息+数据页当时的LSN号

redo的刷写策略

commit;
刷新当前事务的redo buffer到磁盘
还会顺便将一部分redo buffer中没有提交的事务日志也刷新到磁盘
MySQL : 在启动时,必须保证redo日志文件和数据文件LSN必须一致, 如果不一致就会触发CSR,最终保证一致

情况一:
我们做了一个事务,begin;update;commit.
1.在begin ,会立即分配一个TXID=tx_01.
2.update时,会将需要修改的数据页(dp_01,LSN=101),加载到data buffer中
3.DBWR线程,会进行dp_01数据页修改更新,并更新LSN=102
4.LOGBWR日志写线程,会将dp_01数据页的变化+LSN+TXID存储到redobuffer

5.执行commit时,LGWR日志写线程会将redobuffer信息写入redolog日志文件中,基于WAL原则,
在日志完全写入磁盘后,commit命令才执行成功,(会将此日志打上commit标记)
6.假如此时宕机,内存脏页没有来得及写入磁盘,内存数据全部丢失
7.MySQL再次重启时,必须要redolog和磁盘数据页的LSN是一致的.但是,此时dp_01,TXID=tx_01磁盘是LSN=101,dp_01,TXID=tx_01,redolog中LSN=102
MySQL此时无法正常启动,MySQL触发CSR.在内存追平LSN号,触发ckpt,将内存数据页更新到磁盘,从而保证磁盘数据页和redolog LSN一值.这时MySQL正启动
以上的工作过程,我们把它称之为基于REDO的"前滚操作"

image.png

"双一" 标准的其中一个

innodb_flush_log_at_trx_commit=1 #该参数控制redo buffer往磁盘刷写的策略,值可以为0,1,2,默认为1

redo buffer往磁盘刷写要经过文件系统的buffer

0 表示每秒往磁盘刷写一次

1 表示每执行一次commit命令,就往磁盘刷写一次,会影响性能

2 表示每执行一次commit命令,redo buffer就往文件系统的buffer刷写一次,操作系统的buffer每秒往磁盘刷写一次

Innodb_flush_method=(O_DIRECT, fsync)

fsync模式(默认模式)下,都经过os buffer

redo日志记录内存数据页的变化,与内存中数据发生变化的时点相同

O_DIRECT模式下(建议模式),buffer pool直接刷写到disk,不经过os buffer

最高安全模式

innodb_flush_log_at_trx_commit=1

Innodb_flush_method=O_DIRECT

最高性能:

innodb_flush_log_at_trx_commit=0

Innodb_flush_method=fsync

redo日志设置有关的

innodb_log_buffer_size=16777216

innodb_log_file_size=50331648

innodb_log_files_in_group = 3

脏页刷写策略

innodb_max_dirty_pages_pct=75

还有哪些机制会触发写磁盘?

CSR

redo满了

10.2.3 undo
回滚日志.
作用: 在 ACID特性中,主要保证A的特性,同时对CI也有一定功效

redo日志里面的事务不都提交了,有的事务没有,但是会随着提交命令一起写入,但是redo日志会通过TXID(事务id)来记录事务是否提交。在CSR的过程中,先检查数据的LSN和redo日志的LSN,如果不一致,先前滚,然后,如果检测到这个个事务没有提交,会去检测undo日志,将该事务修改之前的状态加载到内存,执行回滚,

(1)记录了数据修改之前的状态
(2)rollback 将内存的数据恢复到修改之前
(3)在CSR中实现未提交数据的回滚操作
(4)实现一致性快照,配合隔离级别保证MVCC,读和写的操作不会互相阻塞

10.2.4 锁
实现了事务之间的隔离功能,InnoDB中实现的是行级锁.
row-level lock
gap
next-lock

10.2.5 隔离级别

select @@tx_isolation; #查看隔离级别

RU 会出现脏读 ,

RC 会出现不可重复读 ,也会出现幻读.

RR 通过MVCC基础解决了不可重复读,但是有可能会出现幻读现象

在RR模式下,GAP和Next-lock进行避免幻读现象,必须索引支持

利用的是undo的快照技术+GAP(间隙锁)+NextLock(下键锁)

transaction_isolation=read-uncommitted

transaction_isolation=read-committed

transaction_isolation=REPEATABLE-READ

MVCC ---> undo 快照