https://www.cnblogs.com/gustavo

Gustavo's Blog

人类的赞歌是勇气的赞歌!

MVCC

原理

体上来讲MVCC的实现是基于ReadView版本链以及Undo日志实现的

MVCC就是在使用READ COMMITTD、REPEATABLE READ这两种隔离级别的事务在执行普通的SELECT操作时访问记录的版本链的过程,这样可以使不同事务的读-写、写-读操作并发执行,从而提升系统性能;

 

InnoDB存储引擎的表来说,它的聚簇索引记录中都包含两个必要的隐藏

trx_id:每次一个事务对某条聚簇索引记录进行改动时,都会把该事务的事务id赋值给trx_id隐藏列。

 

roll_pointer:每次对某条聚簇索引记录进行改动时,都会把旧的版本写入到undo日志中,然后列就相当于一个指,可以通该记录修改前的信息

 

id  1  name  trx id  10  roll_pointer  undo log

 

每次对记录进行改动,都会记录一条undo日志,每条undo日志也都有一个roll_pointer属性

id  1  id  1  id  1  name  name  name  trx id  30  trx id  20  trx id  10  roll_pointer  roll_pointer  roll_pointer

 

ReadView

需要判断一下版本链中的个版本是当前事可见的,readview就是根据规则判断可显示的记录。

 

trx id==creator trx id  trx id < min trx id  trx id > max trx id  min trx id < trx id < max trx id &&trx id in m ids  min trx id < trx id < max trx id trx id not in m ids  ööJLxÅ

 

如果某个版本的数据对当前事务不可见的话,那么着版本链找到下一个版本的数继续照上面的规则继续进行判断,以此推,若是到了最后一个版本,版本的数据仍当前事不可那么就表明该条记录对该事务完全不可见,查询结果就不会包含该条记录

 

见问题

是否解决了幻读

会有幻读

• mvsal -u root  rows In Set UU Sec)  ysql> select  I egtx_isolation  I REPEATABLE-READ  I row in set, I warning (O. 00 sec)  uery OK, O rows affected ( .00 sec)  ysql> select * from account where id>2;  j id I name I balance  3 Lin  100  4 Yan  100  rows in set (0. 00 sec)  2  6  - mvsal •u root -p  mysql) select 00tx_isolation;  "tx_isolation I  I REPEATABLE-READ I  1 row in set, I warning (O. sec)  mysql> begin;  Query OK, O rows affected (O. 00 sec)  mysql> insert into account (id, name, balance) value(5. 'Wei' , 100)  Query OK, I row affected (O. 00 sec)  mysql> comit;  Query OK, O rows affected (O. 01 sec)  mysql>  sql> update account set balance=200 where id=5;  ery OK. I row affected (0. 01 sec)  ysql> select * from account where id>2;  3  4  5  Lin  Yan  wei  100  100  200  7

 

 

InnoDB存储引擎在 RR 级别下通过 MVCC和 Next-key Lock 来解决幻读问题:

 

1、执行普通 select,此时会以 MVCC 快照读的方式读取数据 在快照读的情况下,RR 隔离级别只会在事务开启后的第一次查询生成 Read View ,并使用至事务提交。所以在生成 Read View 之后其它事务所做的更新、插入记录版本对当前事务并不可见,实现了可重复读和防止快照读下的 “幻读

 

2、执行 select...for update/lock in share mode、insert、update、delete 等当前读 在当前读下,读取的都是最新的数据,如果其它事务有插入新的记录,并且刚好在当前事务查询范围内,就会产生幻读!InnoDB 使用 Next-key Lock  (opens new window) 来防止这种情况。当执行当前读时,会锁定读取到的记录的同时,锁定它们的间隙,防止其它事务在查询范围内插入数据。只要我不让你插入,就不会发生幻读 # 参考

 
posted @ 2022-08-20 10:20  BitBean  阅读(46)  评论(0编辑  收藏  举报