# MVCC

多并发版本控制

  • 当前读:`select lock in share mode,select for update, update, insert, delete都是一种当前读,它读取的是最新的数据,并且在读取时保证其它事务不会修改当前记录
  • 快照读:不加锁的非阻塞读;前提是隔离级别不是串行级别;

实现:

  1. 隐式字段:表记录DB_ROW_ID,DB_TRX_ID当前操作此记录的事务ID;DB_ROLL_PTR回滚指针,用于配合undo日志,指向上一个版本;delete_flag

  2. undo log:不同事务或相同事务对同一记录的修改,会导致此记录的undo log成为一记录版本线性表,链首是最新的旧记录,链尾是最早的旧记录

    • Insert Undo Log
    • Update Undo Log
    • Delete Undo Log:purge线程清理DELETED_BIT=true的记录,它维护一个rearview,如果对purege可见,则可安全删除
  3. Read View:已提交读与可重复读区别在于ReadView生成的策略不同,InnoDB为每个事务构造了一个数组,记录并维护系统当前活跃事务的ID 有个当前活跃着的读写事务的列表,也就是begin了还未提交的事务列表。通过这个列表判断某个版本对当前事务是否可见;事务开启时会分配一个ID,这个ID递增的,最新的事务ID值越大

    Creator_trx_id 创建它的事务ID。
    只有对表记录有改动(Insert、Delete、Update)时才会为事务分配事务ID,只读事务中的ID值默认为0
    trx_ids 生成RV时当前系统活跃的读写事务的事务ID列表
    Up_limit_id 活跃事务中最小的事务ID
    Low_limit_id 生成RV时系统应该分配给下一个事务的ID值,系统最大事务ID值,区别于正在活跃的事务ID

设计思路:

  • ReadUncommited:可读到未提交事务修改过的记录,所以直接读取记录的最新版本
  • Serializable:使用加锁的方式访问数据
  • ReadCommitted,RepeatableRead:保证读到已经提交了的事务修改过的记录
    • 可见性算法:修改数据的最新记录中的DB_TRX_ID当前事务ID,与系统当前其它活跃事务ID对比,如果不符合可见性,则顺着DB_ROLL_PTR回滚指针取出Undo Log中的DB_TRX_ID比较,直到找到符合条件的DB_TRX_ID,这个记录就是能看见的最老的版本

ReadCommitted 快照读:事务中每次快照读都生成一个快照和ReadView

RepeatableRead快照读:事务中对某记录的第一次快照读创建一个快照和ReadView,此后调用快照读时调用的是同一个ReadView

# MySql锁类型

  • 共享锁S和排它锁X
    • 读锁是共享锁,通过lock in share mode 实现
    • 写锁是排它锁,会阻塞写锁和读锁,分为行锁和表锁
  • 表锁和行锁
    • 表锁会锁定整张表并阻塞其它用户对表的读写操作
    • 行锁分乐观锁和悲观锁,悲观锁通过for update实现,乐观锁通过版本号实现
# 两个维度
  • 共享锁:读锁(s锁),多个事务对同一数据共享访问,不能操作修改
  • 排他锁(行锁):写锁(X锁)互斥锁,独占锁,事务获得X锁,其它事务就不能获取它的读和写锁,只有获取到排他锁的事务可以进行读取和修改
  • 意向锁(IS)
    • 意向共享锁(表锁)
    • 意向排他锁(表锁)

# SQL执行过程

除从磁盘加载文件和将操作前的数据保存到undo日志中,其它的操作都是在内在中进行的

# Buffer Pool:

更新操作实际在Buffer Pool中执行

# Undo日志文件:

记录修改前的数据

# Redo日志文件:

记录修改后的数据

# Binlog日志文件

逻辑日志,模式:Statement,Row,Mixed

  1. BufferPool中没有数据则从磁盘加载缓存数据到Buffer Pool
  2. 记录更新前的记录数据到Undo Log,便于回滚操作
  3. 更新内存中的数据Buffer Pool
  4. 写Redo日志到Redo Log Buffer
  5. Redo Log Buffer中的日志刷入磁盘(Os Cache)
  6. 准备提交事务,将binlog文件写入到磁盘
  7. 写入binlog文件与位置,写入commit标记
  8. IO线程刷新BufferPool中的脏数据到磁盘文件

db-mysql-sql-13

上次更新: : 5 months ago