mysql-mvcc

事务隔离级别


1. 脏写 一个事务回滚影响了其他已提交事务对此记录的修改

2. 脏读 一个事务读到了未提交事务对此记录修改后的值

3. 不可重复读 一个事务中,读到了相同记录不同的值,这期间有其他事务对此记录进行修改

4. 幻读 一个事务中,每次读的数据都变多

sql标准下的隔离级别

1. read uncommitted 读未提交

2. read committed 读已提交

3. repeatable read 可重复读

4. serializable 串行化

  

read uncommitted 可以读到事务未提交的数据,每次读都读最新的记录即可

serializable mysql规定使用锁

read committed/repeatable read 需要读到已提交的事务记录 需判断记录的版本链中哪个版本是当前事务可见的 这时readview就产生了

 mvcc 其实就是在read committed/repeatable read 隔离级别下,事务在执行过程中select查询时 访问记录版本链的过程

版本链:每条记录都有一个隐藏列roll pointer指向undo日志,除了insert undo日志外,每个undo日志的roll_pointer列都记录上一次事务的undo日志,形成了以最新记录为头结点的版本链

innodb在执行两个事务修改同一条记录的时候,一个事务会给记录加锁,另一个事务等待锁释放才能执行

read view的核心就是确认哪些版本对当前事务是可见的

 read view比较核心的四个属性

  1. m_ids 

    生成read view时,当前系统活跃的读写事务的trx_id值列表

  2. min_trx_id 

    m_ids中的最小值

  3. max_trx_id 

    生成readview时,应该分配给下一个事务的id值

  4. creator_trx_id 

    生成当前readview的事务id

 

  有了readview使用以下的规则,判断某个版本链是否可见

  - 如果被访问记录版本的trx_id与readview的creator_trx_id相同,意味着当前事务访问的是他自己修改或的记录,该版本可以被当前事务访问到

  - 如果被访问版本的trx_id值小于readview的min_trx_id,意味着访问的版本事务已经提交,可以被当前事务访问到

  - 如果被访问版本的trx_id大于readview的max_trx_id,意味着事务是在当前事务之后创建的,不可以被当前事务访问到

  - 如果被访问版本的trx_id在min_trx_id和max_trx_id之间,查看是否在m_ids中,如果在说明创建readview的时候,这个事务是活跃的,不能被访问到,如果不在,说明已经提交,可以被访问到

  如果某个版本的数据对当前事务不可见,就顺着版本链找下一个版本,不可见就不返回

  read committed 跟 repeatable read最大的区别就是生成read view 的时机不同

  READ COMMITTED 事务在每次查询开始的时候都生成一个read view 在同一个事务中每一个查询都生成一个新的read view

  REPEATABLE_READ 在事务第一次读取数据时生成一个read view 以后同一个事务都用同一个read view

  在确定最早产生的read view不会再访问某些update undo日志或者deleted_mark的undo日志的时候,purge线程会把他们真正的删除掉

原文地址:https://www.cnblogs.com/isnotnull/p/14504622.html