[MySQL]redo日志

1.引言

redo日志是innodb特有的日志模块,当然也就位于存储引擎层啦

为了保证事务的持久性,一个很简单的方式就是在事务提交之前,将本次事务所做的修改操作都刷新到磁盘当中.但这种方式也存在着诸多的问题:

  • 如果每一次更新都需要写入磁盘那么这个IO成本有点高.
  • 随机IO刷新起来比较慢,一个事务可能包含多个语句,这些语句可能会造成多个页中的数据被修改,也可能这些页也不相连,就会导致需要进行多次随机IO[随机IO比顺序IO还慢],IO成本过高

其实,为了解决IO成本高的问题,MySQL提出了WAL技术(Write Ahead Log) 

WAL的核心思想在于: 先写日志,在写磁盘.

具体为:当有一条记录需要更新时,InnoDB先把记录写到 redo log当中,并更新内存[buffer pool],这时本次更新就算是完成了.同时innodb也会在合适的时机进行写入磁盘.

1.2redo日志的优点

  • redo日志占用的空间非常小.
  • redo日志是顺序写入磁盘的,即使用的是顺序IO.

redo日志本质上只是记录了一下事务对数据库进行了哪些修改. 

1.3redo日志刷盘的时机

1.log buffer空间不足的时候:

log buffer的逻辑结构是一个循环队列.当前的log buffer可用容量超过50%的时候就会执行刷盘操作.

2.事务提交时.

引入redo日志之后,虽然可以在事务提交时可以不把修改过的buffer pool页面立即刷新到磁盘当中,但是为了保证持久性,必须要把修改的redo日志刷新到磁盘当中.否则一旦系统崩溃,就无法将该事务作出的修改恢复.

3.后台有一个线程,大概一秒刷盘一次.

4.正常关闭服务器的时候,会在关闭之前将所有的redo日志刷盘.

1.4 数据的恢复

redo日志的存在使得MySQL即使异常重启,之前提交的数据记录也不会丢失.这个能力被称作:crash-safe

有了redo日志,事务在提交前总是先写日志,然后在找合适的机会去刷盘,及时发送了宕机数据也可以从redo日志中恢复.

数据的恢复一般有两种方案:

1.4.1使用哈希表

根据redo日志的spaceid(空间ID)和pagenumber(页号)来计算出对应的哈希值,然后把相同页的日志按照执行的先后顺序都放在同一个哈希槽中[用链表连起来],

之后使用哈希表就可以实现精准恢复了,一次性可以将一个页修复好.这样就加快了恢复的速度,而不用随机遍历页了.

1.4.2跳过已经刷新到磁盘的页面

对于已经刷新到磁盘的页面就不用再去恢复了,例如sln的值小于checkpoint的值的redo日志就不需要进行恢复了,因为他已经刷新入盘了.

1.5 其他

redo日志的类型有简单和复杂之分.简单类型的redo日志是纯粹的物理日志,而复杂类型的redo日志兼有物理日志和逻辑日志的特性.

其实在日志的写入中也存在原子性的操作,例如MTR可以包含一组redo日志.在进行崩溃恢复的时候,这一组redo日志被视为一个不可分割的整体来处理.

redo日志被存放在大小为512B的Block(块)中,每一个块被分成了3个部分,

head:一些控制,管理信息12B

body:存放redo日志数据496B

trailer:控制信息4B

redo日志的缓冲区是一片连续的内存空间,由若干个Bolck组成,可以通过启动选项innodb_log_buffer_size来设置他的大小.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值