MYSQL_08MVCC与BufferPool缓存机制
2023-04-16 09:50:35 11 举报
AI智能生成
MVCC与BufferPool缓存机制
作者其他创作
大纲/内容
MVCC
MVCC是在并发访问数据库时,通过对数据进行多版本控制,避免因写锁而导致读操作的堵塞
MVCC通过对数据进行多版本保存,根据比较版本号来控制数据是否展示,从而达到读取数据时无需加锁就可以实现事务的隔离性
实现原理
undo log
通过undo log来保存多版本的数据
innodb在修改数据库数据记录之前会先在undo log中记录回滚日志
内容
执行insert时会对应在undo log中记录一条delete语句,并且会记录这个版本的事务id(txid)
执行update语句会有一条update语句来使之数据恢复到上个版本
主要用于事务回滚和mvcc获取不同事务id对应的数据来实现事务隔离
跟redo log有些区别
undo通过段的形式存储在共享表空间中
redo log存储于日志文件中
undo log的内容变更也会记录到redo log中,从而实现undo log的持久化
undo log实现了数据库快照功能,通过事务id和undo log我们可以找到历史版本的数据
一致性视图
通过一致性视图来保存当前活跃的事务列表
InnoDB为每个事务构造了一个数组,用来保存这个事务启动瞬间,当前正在“活跃”的所有事务ID
记录了当前活跃的事务ID,通过这个数据我们可以判断出来事务执行的先后顺序,事务所能读取的数据版本
数组里面事务ID的最小值记为低水位,当前系统里面已经创建过的事务ID的最大值加1记为高水
版本未提交,不可见
版本已提交,但是是在视图创建后提交的,不可见
版本已提交,而且是在视图创建前提交的,可见
例子
当前有个正在执行事务99,数据行的历史版本为事务id90(1.1)
按照事务的开启时间,分别递增分配了100,101,102三个事务ID(trx id)
在SQL语句执行之前,事务A生成一致性视图【99,100】,事务B生成一致性视图【99,100,101】,事务C生成一致性视图【99,100,101,102】
SQL语句的执行之前生成undo log,通过undo log可以生成历史版本数据快照
事务A的查询执行时,当前数据版本为trx id:101,跟一致性视图【99,100】进行比较,101大于高水位不可见
通过undo log回退到trx id:102版本,102也大于高水位不可见,再回退一个版本到trx id:90,90低于低水位可见,所以事务A读取到的数据为(1.1)
BufferPool缓存
缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用。
为啥不把所有数据都放到缓冲池里
缓存访问快,但容量小
内存访问快,但容量小
只能把“最热”的数据放到“最近”的地方,以“最大限度”的降低磁盘访问
预读
磁盘读写,并不是按需读取,而是按页读取,一次至少读一页数据(一般是4K),如果未来要读取的数据就在页中,就能够省去后续的磁盘IO,提高效率
数据访问,通常都遵循“集中读写”的原则,使用一些数据,大概率会使用附近的数据,这就是所谓的“局部性原理”,它表明提前加载是有效的,确实能够减少磁盘IO
按页(4K)读取
磁盘访问按页读取能够提高性能,所以缓冲池一般也是按页缓存数据
预读机制启示了我们,能把一些“可能要访问”的页提前加入缓冲池,避免未来的磁盘IO操作
InnoDB SQL执行执行流程
加载数据页,把需要修改数据所在的数据页,缓存到Buffer Pool
修改前记录,写undo日志,记录更改前数据,如果事务执行失败,使用undo日志进行数据回滚
更新Buffer Pool中的数据
准备提交事务,写redo日志,保存操作记录。redo日志用来恢复已提交事务的Buffer Pool
准备提交事务,写bin-log日志,保存操作记录。bin-log日志用来恢复磁盘数据
事务提交完成,此时bin-log日志写入成功,且在redo日志中记录commit标记
数据持久化,IO线程不定期把Buffer Pool中的数据随机写入到磁盘,完成持久化
BufferPool 缓存机制,可以保证每个更新请求都是更新内存 BufferPool,然后顺序写日志文件,同时还能保证各种异常情况下的数据一致性
0 条评论
下一页