MYSQL-->InnoDB引擎底层原理( 三 )


  1. 客户端A对innoDB存储引擎的表进行增删改事务操作
  2. 先访问内存结构中的缓冲池,如果增删改数据在其中不存在,
    就会从磁盘中读取数据再刷新到缓冲池(这个数据必须是唯一索引 , 否则会先进入到更改缓冲区)
  3. 在缓冲池中变成脏页,并记录在redolog buffer中,后直接刷新到磁盘中
  4. 如果脏页在一段时间后刷新到磁盘中报错了,可以通过redo log进行恢复 。

MYSQL-->InnoDB引擎底层原理

文章插图
使用redo log直接刷新到磁盘结构的好处
事务一般是一组多条的增删改查操作 , 故事务提交的时候会随机的操作多条的记录 。
这些记录会操作多条数据页,这样会产生大量的随机磁盘IO
而直接将redo log文件异步刷新到磁盘io中,由于它是日志文件,日志文件都是追加的,此时是顺序磁盘IO , 这样会节约大量的磁盘IO
这种机制叫WAL(Write-Ahead Logging)(先写日志)
然后过一段时间脏页日志才会刷新到磁盘中 。
故俩份日志是循环清理的
事务的redo log日志是为了解决脏页刷新到磁盘出错时进行数据的恢复使用的,用来保证数据的持久性
undo logundo log日志是用来保证事务的原子性的 。
undo log也叫回滚日志,用于记录数据被修改前的信息,作用为:提供回滚和MVCC
redo log记录的是物理日志!
undo log记录的是逻辑日志,可以认为当执行delete 一条记录时,undo log中会记录一条对应的insert记录,反之同理 。
当执行rollback时,就可以从undo log中的逻辑记录读取到对应内容,从而进行回滚 。
Undo log销毁
undo log在事务执行时产生 , 事务提交时,并不会马上删除undo log,因为这些日志可能还用于MVCC
Undo log存储
undo log采用,段的方式进行管理和记录,存放在前面介绍的rollback segment回滚中,内部包含了1024个undo log segment
这个段是逻辑存储结构的段哦~
MVCC(多版本并发控制)(高频面试题)MVCC的几个基本概念当前读我们读取的是记录的最新版本 , 读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁,
对于我们日常的操作,如:select...lock in share mode(共享锁),select...for update,update , insert,delete(排他锁)
都是一种当前读 。
案例:
在RR的隔离级别下
  1. 事务A进行查询操作,事务B进行更新操作并提交事务
  2. 事务A使用当前读select...此时读取的是事务B更新之前的数据(原因是隔离级别)
  3. 事务A使用select...lock in share mode(当前读)此时读取的是事务B更新之后的数据 。
快照读简单的select(不加锁)就是快照读,读取的是记录数据的可见版本,可能是历史数据,不加锁是非阻塞读 。
  1. Read Committed隔离级别:每次select都生成一个快照读
  2. Repeatable Read隔离级别:开启事务后第一个select语句才是快照读的地方(后续查的就是这个快照数据)
  3. Serializable隔离级别:快照读会退化为当前读
MVCC介绍全称Multi-Version Concurrency Control 多版本并发控制 。
指的是维护一个数据的多个版本,使得读写操作没有冲突 。
快照读为MYSQL实现MVCC提供了一个非阻塞读功能,MVCC的具体实现,还需要依赖,数据库的三个隐藏字段、
undo log日志、readView
MVCC-实现原理记录中的隐藏字段当我们创建了表除了自己本身创建的字段,innoDB引擎会自动给我们创建三个字段
分别是:
  1. DB_TRX_ID
  2. DB_ROLL_PTR
  3. DB_ROW_ID
隐藏字段含义DB_TRX_ID最近修改事务ID,记录插入这条记录或者最后一次修改该记录的ID(事务id)DB_ROLL_PTR回滚指针,指向这条记录的上一个版本,用于配合undo log指向上一个版本DB_ROW_ID隐藏主键,如果表结构没有指定主键,就会生成该隐藏字段
可以查看表空间文件内容来查看隐藏字段信息
事务id是自增的!
在MYSQL中提供了一个命令来查看表空间文件的记录信息
ibd2sdi xxx.ibdundo log版本链回滚日志,在insert、update、delete的时候产生的便于数据回滚的日志
当insert的时候,产生的undo log日志只在回滚时需要,在事务提交后 , 可被立即删除 。

推荐阅读