千人千面MVCC
每个事务可以读到特定版本的数据,就是MVCC
由于undo log的存在,可以从最新版本推算之前版本
undo log的作用
- 回滚事务roll back
-
快照读(一致性非锁定读)
普通的select就是快照读
不锁定数据的情况下,读取数据的特定历史版本
- 版本由事务的具体需求确定:
- 读已提交:根据每次SELECT时,其他事务的提交情况
比如trx_id=230修改了name= “d”,但是还没有提交事务,虽然事务已经把数据的内容修改掉了,但是其他事务去读取这一行数据的时候,是不能把这一行给读取出来的,这是读已提交的时候,我现在select的时候,发现未提交怎么办,那就用undo还原成未修改的状态。也就是说读取的是190这个事务的提交的数据,这个数据一定是提交了,因为只有190提交了,230才能修改。所以我select的时候,展示的是name=’c’这条数据 。但是,如果trx_id=230提交了,那么select的时候展示的就是name=’d’这条数据了。
- 可持续读:根据事务开始时,其他事务的提交情况
比如说,事务a在158之后这个时刻,它begin了,有两个事务更改了字段并提交了,那么它select name这个字段的时候,只能拿到name=’b’这个版本的事务,这叫可持续读。怎么展示之前版本,就用undo log。
当前读(一致性锁定读)

- 读取数据的当前版本,并加锁
- 若当前版本已经被加锁且不兼容,则阻塞等待
- X锁:UPDATE、DELETE、SELECT FOR UPDATE 写互斥锁 不允许别人读写
- S锁:SELECT IN SHARE MODE 读共享锁 不允许别人写
隔离问题
- 脏读:读到了其他事务未提交的数据
- 不可重复读:同样的查询读到的数据内容不一样
- 幻读:同样的查询读到了更多的数据
如何解决幻读问题
- MySQL在可重复读级别时,通过Next-Key锁解决了幻读问题
- Next-key锁是行锁+间隙锁


