MVCC

MVCC
    一些隐藏字段
        DB_ROW_ID用于存储删除版本号
        DB_TRX_ID用于存储事务ID
        DATA_ROLL_PTR指向UNDO LOG RECORD,UNDO LOG RECORD拥有更新之前的所有数据
        创建时间(版本号)
        删除时间(版本号)
    操作
        新增
            创建时间DB_TRX_ID
            删除时间未定义
        修改
            复制一行作为新行
                创建时间DB_TRX_ID
                删除时间未定义
            旧行
                修改删除时间为DB_TRX_ID
        删除
            修改删除时间为DB_ROW_ID
        查询
            不做任何修改,只读
    原理
        新增
            保存当前的事务ID作为当前行的版本号
        修改
            复制一行新数据,新行的版本号为系统版本号,旧行数据的删除版本号为系统版本号
        删除
            修改删除行的删除版本号为当前系统版本号
        查询
            行版本号小于等于当前系统版本号
            删除版本要么没定义或者大于当前系统版本号
     另外
            怎么保证先建立的事务又为提交的修改数据,不被后建立的事务读取呢?根据READ VIEW,每当开启一个事务时,把当前活动的事务都复制进READ VIEW列表。
 
 
 
事务隔离级别(transction isolation level) select @@tx_isolation;
    未提交读(RU)
            READ UNCOMMITED
                指的是在事务未提交之前的数据库操作,其他事务也可以读取,会造成脏读。
            例如:
                事务A开启事务->事务B开启事务->事务B修改数据->事务A查询数据会得到B修改后的数据
 
    提交读(RC)
             READ COMMITED
                指的是在事务未提交之前的数据库操作,其他事务不可以读取,不会脏读,但是会造成不可重复读。
            例如:
                事务A开启事务->事务B开启事务->事务B修改数据->事务A查询数据不会得到B修改后的数据->事务B提交事务->->事务A查询数据会得到B修改后的数据(不可重复读)
 
    可重复读(RR)
            REPEATABLE READ
                基于行排它锁和MVCC,解决了不可重复读的问题,但是会造成幻读。
            例如:
                事务A开启事务->事务B开启事务->事务B新增数据->事务A查询数据不会得到B新增后的数据->事务A新增数据会提示主键冲突(幻读)
 
     串行化SERIALIZABLE
            强制加锁串行话,避免幻读的问题,但是会导致大量的超时和锁争用的问题,一般用不上。
原文地址:https://www.cnblogs.com/godehi/p/13091093.html