mysql的读已提交和可重复读
所属分类 mysql
浏览量 975
隔离级别
Read Committed 和 Repeatable Read
RC每次读生成最新的ReadView,这个ReadView会记录当前的事务情况,即哪些事务已经提交了,哪些未提交。
然后就可以到当前页+undo页里面读到已经提交的数据了
RR只在第一次读的时候生成一个ReadView,所以可以保证可重复复读。
未提交读不关心当前的事务情况,直接读B+树下的最新数据页,里面的记录可能是未提交的
MVCC只在 Read Committed 和 Repeatable Read 两个隔离级别下工作
MVCC实现机制 隐藏字段 ReadView Undolog
共享锁和排他锁
共享锁也叫S锁/读锁, 作用是锁住当前事务select的数据行,其实事务可以读这些数据行,但不能写
SELECT ... LOCK IN SHARE MODE;
排他锁也叫X锁/写锁,使用了排他锁的数据行,其他事务既不能读也不能写
InnoDB 引擎 为insert update delete操作中涉及的数据自动加排他锁(根据where条件语句)
对于一般的select语句,InnoDB不会加任何锁,可加FOR UPDATE,显式地加排他锁
SELECT ... FOR UPDATE;
加过排他锁的数据行在其他事务中不能修改
不能通过for update和lock in share mode的方式查询数据
但可以直接通过普通select from 查询数据(查到的是已提交的数据)
因为普通查询没有任何锁机制
查询操作如不显式加锁,普通select语句无锁
无锁的实质是MVCC
Serializable隔离级别的select有锁)
insert update delete操作有排他锁
多版本并发控制(Multiversion Concurrency Control)
引入MVCC后,只有写写之间相互阻塞,其他三种操作都可以并行
InnoDB通过undo log保存每条数据的多个版本
可以读不通的版本,每个事务读到的数据版本可能是不一样的
MVCC只在 Read Committed 和 Repeatable Read 两个隔离级别下工作
MVCC实现机制 隐藏字段 ReadView Undolog
InnoDB存储引擎在每行数据的后面添加了三个隐藏字段
DB_TRX_ID (6字节)
表示最近一次对本记录行作修改(insert | update)的事务ID
InnoDB会把delete操作认作update
不过会更新一个另外的删除位,将行表示为deleted 并非真正删除
DB_ROLL_PTR (7字节)
回滚指针,指向当前记录行的undo log信息
DB_ROW_ID (6字节)
随着新行插入而单调递增的行ID
当表没有主键或唯一非空索引时,innodb会使用这个行ID自动产生聚簇索引
如果有聚簇索引就不会包含这个行ID了
DB_ROW_ID跟MVCC关系不大
Read View 读视图,跟快照、snapshot是一个概念
主要用来做可见性判断
Read View里面的变量
low_limit_id
目前出现过的最大的事务ID+1,即下一个将被分配的事务ID
up_limit_id
活跃事务列表trx_ids中最小的事务ID(如果trx_ids为空,则up_limit_id 为 low_limit_id)
trx_ids
Read View创建时其他未提交的活跃事务ID列表
创建Read View时,将当前未提交事务ID记录下来,后续即使它们修改了记录行的值,对于当前事务也是不可见的
注意:不包括当前事务自己和已提交的事务(即只包括正在内存中的事务)
creator_trx_id
当前创建事务的ID,是一个递增的编号
Undo log
Undo log中存储历史版本数据,当一个事务需要读取记录行时,如果当前(最新)记录行不可见
可以顺着undo log链找到满足其可见性条件的记录行版本
MySQL事务机制
mysql MVCC 和 事务隔离级别
Mysql锁机制
Mysql事务隔离级别
innodb mvcc
InnoDB锁机制之Gap Next-Key Record Lock
上一篇
下一篇
linux时区设置
伤感情歌系列
甜歌系列
springboot基础配置
mysql redo undo binlog
tomcat8 嵌入式 servlet 实例