8.innodb存储引擎(mysql版本8.0.20)-2 InnoDB核心特性 -- 事务

7.1 介绍?
Transaction.交易
为了保证在数据中,发生交易类操作时,保证"平衡"

7.2 事务的特性(Atomicity, Consistency, Isolation, Durability. )

A : 原子性
事务中的所有查询,要么全成功,要么全失败.

C : 一致性
事务发生前,中,后.数据保证最终一致性.

I : 隔离性
并发事务期间,事务之间互不干扰.

D : 持久性
事务一旦提交.永久生效.

7.3 事务的生命周期

7.3.1 标准事务控制语句

begin;/start transaction;

DML 语句 …

commit;

begin;/start transaction;

DML 语句 …

rollback

7.3.2 autocommit自动提交

如果没有显式的开启事务(begin)
MySQL 会自动在DML语句执行前,加上begin;

[begin]
update t1 set name='a’m where id=1;
commit;
select * from t1;

所以,在需要事务性支持.手工执行begin开启事务即可.

7.3.3 隐式 提交和回滚

begin;
DML1
DMl2
commit;

#隐式提交情况
begin
a
b

SET AUTOCOMMIT = 1
导致提交的非事务语句:
DDL语句: (ALTER、CREATE 和 DROP)
DCL语句: (GRANT、REVOKE 和 SET PASSWORD)
锁定语句:(LOCK TABLES 和 UNLOCK TABLES)

导致隐式提交的语句示例:
TRUNCATE TABLE
LOAD DATA INFILE
SELECT FOR UPDATE

#隐式回滚

会话窗口被关闭。
数据库关闭 。
出现事务冲突(死锁)。

7.3.4 事务的隔离级别
a. 介绍
RU : read-uncommitted 读未提交
RC : read-committed 读已提交
RR : repeatable-read 可重复读
SE : serializable 可串行化

READ COMMITTED
READ UNCOMMITTED
REPEATABLE READ
SERIALIZABLE

b.
配置方法
mysql> select @@transaction_isolation;
±------------------------+
| @@transaction_isolation |
±------------------------+
| REPEATABLE-READ |
±------------------------+

mysql> set global transaction_isolation=‘read-committed’;

c. 隔离级别特性说明

问题读:
脏读 : 事务中读取到了别的事务未提交的数据.
不可重复读 : 同一个事务内,读取相同数据时,产生了不同的结果.
幻读 : 在同一个事务内,读取到了幻影数据.

RU : 脏读 不可重复读 幻读
RC : 不可重复读 幻读
RR : 幻读.加上锁(next lock)的机制可以有效0避免幻读.
SE : NUL

d. 各种问题读的演示

看操作视频.

扩展内容:

  1. 事务的ACID如何保证?

8.1 名词认识

a. redo log 重做日志
ib_logfile0~N 日志文件
log_buffer 缓冲区

b. undo log 回滚日志
undo_001~002 .ibu

c. WAL 日志先行
write ahead log

落盘数据时,先写日志,再写数据.

d. LSN 值序列号.
标识了产生redo日志的字节量.单调递增
哪几个位置会有LSN信息
page lsn
redo buffer
redo log
system

e. # DB_TRX_ID(6字节) 事务ID号
InnoDB会为每一个事务生成一个事务号,伴随着整个事务生命周期.

f. # DB_ROLL_PTR(7字节) 回滚指针
rollback 时,会使用 undo 日志回滚已修改的数据。DB_ROLL_PTR指向了此次事务的回滚位置点,用来找到undo日志信息。

g.# 脏页: Dirty Page
内存脏页,内存中发生了修改,没写入到磁盘之前,我们把内存页称之为脏页.

#CheckPoint
CKPT:检查点,就是将脏页刷写到磁盘的动作

8.2 事务工作逻辑-REDO

(老师讲解自己理解内容)理解过程:在事务过程中 ,首先将数据页(头部信息有lsn) 加载到buffer pool找到所要修改的数据行,在内存中修改数据页的同时,会产生数据页的变化日志,包括数据页的
修改内容,(log—_ buffer)日志中的lsn也会发生变化,mysql为加快提交速度,只将redo日志刷新到磁盘日志文件iblog_file当中(数据不用存放,存放数据的话并发度多,数据页加多,会导致IO密集)

宕机会不会丢数据?
mysql有自动故障恢复的特性,通过数据页中的数据和数据变化存放的日志一起放到内存buffer pool中进行重做redo出原来的数据

事务中的DML语句的逻辑过程:加载数据页到内存,修改数据内容,在内存的log_buffer中产生新的日志,更新内存中日志中lsn号码

百度查找
redo log被引入来解决这个问题:当数据修改时,除了修改Buffer Pool中的数据,
还会在redo log记录这次操作;当事务提交时,会调用fsync接口对redo log进行刷盘。
如果 MySQL 宕机,重启时可以读取redo log中的数据,对数据库进行恢复。redo log采用的是 WAL(Write-ahead logging,预写式日志),
所有修改先写入日志,再更新到Buffer Pool,保证了数据不会因 MySQL 宕机而丢失,从而满足了持久性要求。

作用: 主要保证ACID中的D特性. A C 也有间接保证
在Crash Recovery(自动故障恢复) ,实现了前滚的功能

8.3 事务工作逻辑-UnDO
存储回滚日志信息. 逆反操作.

(老师讲解自己理解内容)undo
逻辑过程理解:先加载数据页到内存,给数据页申请专用的ID号和在undo中申请专用的slot(存放日志),把slot的指针号码存放到数据页头部信息,在修改数据内容时,
将数据页头部的DB_TRX_ID和 DB_ROLL_PTR存放到redo日志中,(把事务要修改的数据修改之前的数据)逆反操作存放到undo日志中,在undo日志中存完之后,开始修改数据页,
如果发生提交,mysql宕机将,redo写到磁盘中,如果没有提交,mysql宕机,可以通过数据页头部的DB_TRX_ID和 DB_ROLL_PTR找到undo中的位置点,将数据读取进行回滚

先做redo(前滚)在做undo(回滚)

undo存放的是逻辑日志,redo存放的是逻辑日志和物理日志,主要是物理日志

百度查找
当事务回滚时能够撤销所有已经成功执行的 SQL 语句。
InnoDB 实现回滚,靠的是undo log:当事务对数据库进行修改时,InnoDB 会生成对应的undo log;
如果事务执行失败或调用了rollback,导致事务需要回滚,便可以利用undo log中的信息将数据回滚到修改之前的样子。

redo log用于保证事务持久性;undo log则是事务原子性和隔离性实现的基础。

在ACID中主要保证 A的特性 CI有间接保证
在 CR过程中,通过数据页头部的DB_TRX_ID和 DB_ROLL_PTR或者回滚信息位置.将事务回滚.

综上所述:
CR的过程,对比日志和数据页LSN,判断是否需要CR.
先进行REDO前滚,再进行undo回滚.

8.4 C特性如何保证
DWB,CR共同保证数据最终一致

8.5 I 特性如何保证
隔离级别 : 提供读的隔离.
MVCC : 多版本并发控制. (实际上就是保存了数据在某个时间节点的快照)使用了UNDO快照(修改数据前,记录上一版本的信息(逆反操作),生成undo信息快照,检测锁的冲突时会有写的隔离,在读时都可以拿到)
RC : 每次做新的查询,都会获得一次全新的readview(语句级别).
RR : 在开启时候后,第一次查询数据时,就会生成一致性的readview.一直持续到事务结束.一致性快照读(整个事务级别).

lock (引擎层)
record lock 行锁(记录锁)事务没有确认提交,另一用户同时也对这一行进行操作,所针对行就会锁住
RR 级别下:
gap lock (在辅助索引的间隙上)间隙锁(事务没有确认提交,另一用户同时也对这一间隙进行操作,在操作行之外,所涉及到的间隙也会锁住)
例子:
update t1 set sal=3000 where sal>4000
insert into t1 vaules(22222,‘asd’,4100) 大于4000的间隙在本事务没有结束时从另一shell连接的同一数据库操作,不能插住,会被锁住

next lock = record + gap 两种锁的相加

锁只能降低锁的范围,不能改变锁的机制
优化时可以通过优化查询语句逻辑,进行优化

检测或监控锁等待的方法
mysql> select * from sys.innodb_lock_waits\G
mysql> select * from performance_schema.threads where PROCESSLIST_ID=17;
mysql> select * from events_statements_history where thread_id=57\G

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值