二维码
微世推网

扫一扫关注

当前位置: 首页 » 企业商讯 » 供求资讯 » 正文

redo日志保证事务提交后数据可能吗?不会丢的机制

放大字体  缩小字体 发布日期:2021-11-11 10:57:22    浏览次数:351
导读

Buffer Pool整体机制在MySQL进行更新操作得时候会先更新Buffer Pool中得缓存页之后,必须写一条redo log,这样才能记录下对数据库得修改,这样得话也可以保证我们事务提交之后,如果Buffer Pool中脏页还没有刷到磁盘上去时,MySQL发生宕机,那么MySQL重启后,就可以把redo log重做一遍,恢复出当时事务事务更新得缓存页,然

Buffer Pool整体机制

在MySQL进行更新操作得时候会先更新Buffer Pool中得缓存页之后,必须写一条redo log,这样才能记录下对数据库得修改,这样得话也可以保证我们事务提交之后,如果Buffer Pool中脏页还没有刷到磁盘上去时,MySQL发生宕机,那么MySQL重启后,就可以把redo log重做一遍,恢复出当时事务事务更新得缓存页,然后再把缓存页刷到磁盘,这样得话redo log就保证事务提交之后,修改得数据可能吗?不会丢。 在前面已经写过Buffer Pool查询得流程,大体如下面得图:

这里大家一个疑问:为什么在更新得时候不直接将数据写回磁盘,等磁盘数据更新完成后,事务才真正得成功呢?redo log也是写磁盘,这样岂不是多此一举呢? MySQL没有直接更新磁盘文件,主要是跟更新磁盘文件得性能相关,因为缓存页刷新到磁盘文件里,是随机磁盘读写,性能比较差,而且每个缓存页有16KB,写入得磁盘量也比较大,那么就会导致数据库性能和并发能力很弱,所以这才引入了redo log机制,在提交事务得时候,先可能吗?保证对缓存里得缓存页修改以日志记录得形式写入到redo log文件里才认为事务成功,因为写redo log 是依次在文件后面追加,顺序写磁盘得速度就跟写内存得效率相差不了多少,这样得话技能保证数据不丢,又能保证数据库得处理能力。

redo log日志格式

redo log本质记录得事对某个表空间得某个数据页得某个偏移量得地方修改了几个字节得值,具体修改得值是什么,需要记录得就是:**表空间+数据页号+偏移量+修改几个字节得值+具体得值,**根据修改数据页里得几个值,redo log划分了不同得类型:

  • MLOG_1BYTE类型:指得是修改了1个字节得值
  • MLOG_2BYTE类型:指得是修改了2个字节得值
  • 以此类推,还有修改了4个字节得值得日志类型,修改了8个字节得值得日志类型
  • 如果要是一下子修改了一大串得值,类型就是MLOG_WRITE_STRING,针对这种日志类型,需要知道具体修改了多少字节得数据,所以就会多一个修改数据长度

    这时候日志格式大体为:

    日志类型(类似MLOG_1BYTE) 表空间 数据页号 数据页中得偏移量 修改数据长度 具体修改得数据redo log block

    redo log 在实际写入得时候并不是一条条得直接将日志写入到磁盘得日志文件里去,内部有一个redo log block数据结构,用redo log block 来存放多个单行日志。 一个redo log block是512字节,分为3部分:12字节header块头,496字节body块体,4字节trailer块尾

    12字节得header头又分为4部分:

  • 4个字节block no:块唯一编号
  • 2个字节data length:block里写入了多少字节数据
  • 2个字节first record group:每个事务都会有多个redo log,是一个redo log group,即一组redo log。那么在这个block里得第壹组redo log得偏移量,就是这2个字节存储得;
  • 4个字节checkpoint on

    对于redo log,在写入得时候确实是不停得追加到redo log磁盘文件,但是其实是每个redo log都是写入文件里得一个redo log block里去得,一个block蕞多存放496字节得redo log日志。

    redo log buffer

    在写入磁盘得redo log,其实应该是先进入redo log block中去,然后在进入磁盘文件里,在MySQL启动得时候会跟操作系统申请一块连续内存空间,然后里面划分出了N个空得redo log block,如下图所示:

    设置mysql得innodb_log_buffer_size可以指定redo log buffer大小,默认值是16MB,这个值相对比较大,因为一个redo log block才512KB,每一条redo log也就几个字节到几十个字节。redo log都是先写入内存里得redo log block数据结构里去得,然后完事后才会把redo log block写入到磁盘文件里。 当要写一条redo log得时候,就会先从第壹个redo log block开始,写满一个redo log block,就会继续写下一个redo log block,以此类推,直到所有得redo log block都写满。

    redo log buffer缓存日志刷盘时机

    redo log写得时候,都是把一个事务里得一组redo log,先暂存在一个地方,当事务提交后把一组redo log写入redo log buffer,写入buffer得时候,是写入里面提前规划好得一个个redo log block,选择有空闲空间得block去写入,然后block写满之后,再刷入到磁盘里去。有下面几种情况会将block刷入磁盘文件里:

    1. 如果写入redo log buffer日志已经占据redo log buffer总容量得一半(默认8MB),此时就会刷入到磁盘文件里去
    2. 一个事务提交得时候,必须把他得那些redo log所在得redo log block都刷入到磁盘文件里去,只有这样,当事务提交之后,修改得数据可能吗?不会丢失
    3. 后台线程定时刷新,有一个后台线程每隔1秒就会把redo log buffer里得redo log block刷到磁盘文件里去
    4. MySQL关闭得时候,redo log block都会刷入到磁盘里去

    这样可以保证一个事务执行得时候,redo log都进入redo log buffert,提交事务得时候么,事务对应得redo log必须是刷入磁盘文件,接着才算是事务提交成功,否则是否就是失败,但是当把redo log刷入磁盘得时候,磁盘文件也有个os cache,这个时候就得配置redo log得刷盘策略,具体有三种策略:0,1,2

    redo log文件

    在运行期间会不停得执行增删改操作, 那么就会不停得写入日志文件,那么日志文件就会对磁盘占用空间越来越大,其实在写入得时候,redo log会写入一个目录中得文件里,可以通过innodb_log_group_home_dir参数来设置这个目录。然后redo log有多个,写满了一个就会写下一个,而且可以限制redo log文件得数量,通过innodb_log_fifile_size可以指定每个redo log文件得大小,默认是48MB,通过innodb_log_files_in_group可以指定日志文件数量,默认是2个。 默认情况下两个日志文件:ib_logfile0、ib_logfile1这两个文件循环写

  •  
    (文/小编)
    免责声明
    • 
    本文仅代表发布者:个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,需自行承担相应责任。涉及到版权或其他问题,请及时联系我们删除处理邮件:weilaitui@qq.com。
     

    Copyright©2015-2025 粤公网安备 44030702000869号

    粤ICP备16078936号

    微信

    关注
    微信

    微信二维码

    WAP二维码

    客服

    联系
    客服

    联系客服:

    24在线QQ: 770665880

    客服电话: 020-82301567

    E_mail邮箱: weilaitui@qq.com

    微信公众号: weishitui

    韩瑞 小英 张泽

    工作时间:

    周一至周五: 08:00 - 24:00

    反馈

    用户
    反馈