数据库笔记
MVCC
MVCC = undo + read-view
为了隔离性而服务
定义:
MVCC:多版本并发控制机制,在 读已提交和可重复读 隔离级别下实现了MVCC机制
特点:
不通过加锁,来实现事务之间的隔离性
实现原理
undo日志版本链
定义:
undo日志版本是指 一行数据被多个事务依次修改过后, **MySQL会保留每次操作前的数据。**并用 trx_id【事务id】 和 roll_pointer 【回滚指针】将undo日志串联起来,形成历史记录版本链。
特别的:
对于删除的情况
- 会将版本链上最新的数据复制一份
- 然后将trx_id修改成删除操作的trx_id
- 在该条记录的头信息里面的 delete_flag 标记位上置为true
特点:
- 对于多个事务,日志版本链只有一份
- 事务id和回滚指针 是隐藏的字段
一致性视图 read-view
定义:
当事务开启时,执行任何的查询SQL,会生成当前事务的 一致性视图
组成:
- 视图数组
- 由当前所有未提交的事务id组成
- 已创建的最大事务id
{ [未提交id1,未提交id2,未提交id3,未提交id4] max_id }
注意:
事务id在==执行第一个DML语句时,才会生成,== 而不是在begin/start transaction生成。
版本链比对规则
readview:{ [200],300 }
规则:
- 执行查询语句
- 版本链从上往下寻找,如果 delete_flag == true,不返回数据。反之:
- 如果trx_id 落在 绿色部分(trx_id < min_id),表示该版本由已经提交的事务生成,可见
- 如果trx_id 落在 红色部分(trx_id > max_id),表示该版本由未提交的事务生成,不可见
- 如果trx_id 落在 黄色(min_id < trx_id < max_id)
- 如果trx_id 不存在 视图数组([200]) 中,表示该版本由已经提交的事务生成,可见
- 如果trx_id 存在 视图数组([200]) 中,表示该版本由未提交的事务生成,不可见
MVCC读已提交
实现了MVCC机制
特点:
- read-view 数组在每次查询动态变化,实现了可以读取已经提交事务修改的特性
MVCC可重复读
实现了MVCC机制
特点:
- ==read-view 数组生成后就固定不变,==实现了隔离性。
BufferPool
BufferPool在 引擎层 由InnoDB实现,基于LRU算法
为什么设计BufferPool?
因为没有BufferPool,一次请求就需要对磁盘进行一次 随机读写I/O更新磁盘数据,性能差;
虽然设计BufferPool,会有对日志文件的读写,但对日志文件是顺序读写I/O,性能会比随机读写I/O高很多
一条sql的执行(服务层)
一条DMLsql的执行 (引擎层)
- 从磁盘ibd文件中加载缓存数据
- 将旧值写入undo日志文件 【版本链、事务提交失败回滚】
- 更新BufferPool中的数据
- 写redo日志缓存
- 写redo日志文件 【事务提交成功,系统宕机时恢复BufferPool数据】
- 写bin-log日志文件 【事务提交成功,系统宕机时恢复磁盘数据】
- 写commit标记到redo日志文件 【确保redo和bin-log一致性】
- 后台线程随机将BufferPool修改的数据以页为单位写入磁盘ibd文件