Mysql基础(十):redo log文件的样子

目录

1、redo log含义

2、redo log类型

3、redo log格式

4、redo log写磁盘过程

4.1、redo log里记录了:

4.2、redo log block

4.3、redo log buffer

4.4、写磁盘过程

5、 redo log buffer中缓冲日志,什么时候可以写入磁盘?

6、日志文件就用一个写入全部的redo log?


1、redo log含义

        redo log里本质上记录的就是在对某个表空间的某个数据页的某个偏移量的地方修改了几个字节的值,具体修改的值是什么,他里面需要记录的就是表空间号+数据页号+偏移量+修改几个字节的值+具体的值。

2、redo log类型

    所以根据你修改了数据页里的几个字节的值,redo log就划分为了不同的类型。

  •  MLOG_1BYTE类型的日志指的就是修改了1个字节的值;
  • MLOG_2BYTE类型的日志指的就是修改了2个字节的值,以此类推;
  • MLOG_4BYTE类型的日志指的就是修改了4个字节的值的日志类型;
  • MLOG_8BYTE类型的日志指的就是修改了8个字节的值的日志类型;
  • MLOG_WRITE_STRING,就是代表你一下子在那个数据页的某个偏移量的位置插入或者修改了一大串的值。

3、redo log格式

其实一条redo log看起来大致的结构如下所示:

日志类型(就是类似MLOG_1BYTE之类的),表空间ID,数据页号,数据页中的偏移量,具体修改的数据
   大致就是一条redo log中依次排列上述的一些东西,这条redo log表达的语义就很明确了。
  • 类型是什么,类型就告诉了你他这次增删改操作修改了多少字节的数据;
  • 在哪个表空间里操作的,这个就是跟你SQL在哪个表里执行的是对应的;
  • 在这个表空间的哪个数据页里执行的
  • 在数据页的哪个偏移量开始执行的
  • 具体更新的数据是哪些呢

注意:如果是MLOG_WRITE_STRING类型的日志,因为不知道具体修改了多少字节的数据,所以其实会多一个修改数 据长度,就告诉你他这次修改了多少字节的数据,如下所示他的格式:

日志类型(就是类似MLOG_1BYTE之类的),表空间ID,数据页号,数据页中的偏移量,修改数据长度,具体修改的数据

4、redo log写磁盘过程

4.1、redo log里记录了:

表空间号+数据页号+数据页内偏移量+修改了几个字节的数据+实际修改数据
        就是简简单单这么一条日志,所以大家可以想一下,redo log就是按照上述格式,一条一条的直接就写入到磁盘上的日志文件里去了吗?
实际上redo log不是一行一行的写入redo log中,而是首先用一个redo log block存放多个单行日志。

4.2、redo log block

        一个redo log block是512字节,这个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 block里去的,一个block最多放496字节的日志。然后redo log block放到redo log中,一个redo log文件包含多个redo log block。

        写文件的时候,可以按照字节,一个字节一个字节的写入的,文件里存放的东西就是很多很多字节,依次排开,然后其中可能512个字节组合起来,就固定代表了一个redo log block。

        如果依次在磁盘文件里的末尾追加不停的写字节数据,就是磁盘顺序写;但是假设现在磁盘文件里已经有很多很多的redo log block了,此时要在磁盘里某个随机位置找到一个redo log block去修改他里面几个字节的数据,这就是磁盘随机写

总结:平时我们执行完增删改之后,要写入磁盘的redo log,其实应该是先进入到redo log block这个内存数据结构里去的,然后再进入到磁盘文件里。

4.3、redo log buffer

         redo log buffer其实就是MySQL在启动的时候,就跟操作系统申请的一块连续内存空间,大概可以认为相当于是buffer pool吧。那个buffer pool是申请之后划分了N多个空的缓存页和一些链表结构,让你把磁盘上的数据页加载到内存里来的。

        redo log buffer也是类似的,他是申请出来的一片连续内存,然后里面划分出了N多个空的redo log block。

        通过设置mysql的innodb_log_buffer_size可以指定这个redo log buffer的大小,默认的值就是16MB,其实已经够大了,毕竟一个redo log block才512自己而已,每一条redo log其实也就几个字节到几十个字节罢了。
1)、 redo log buffer里所有的redo log block都写满了呢?
强制将redo log block刷入磁盘。

4.4、写磁盘过程

        redo log block刷入磁盘文件,其实就是把512字节的redo log block追加到redo log日志文件里
去就可以了 ,在磁盘文件里不停的追加一个又一个的redo block。

注意:其实在我们平时执行一个事务的过程中,每个事务会有多个增删改操作,那么就会有多个redo log,这多个redo log就是一组redo log,其实每次一组redo log都是先在别的地方暂存,然后都执行完了,再把一组redo log给写入到redo log buffer的block里去的。

2)、如果一组redo log实在是太多了,那么就可能会存放在两个redo log block中

3)、 如果一个redo log group比较小,那么也可能多个redo log group是在一个redo log block里。 

5、 redo log buffer中缓冲日志,什么时候可以写入磁盘?

redo log buffer的缓冲机制: r edo log 在写的时候,都是一个事务里的一组redo log ,先暂存在一个地方,完事儿了以后把一组 redo log 写入 redo log buffer。写入redo log buffer时,是写入里面提前划分好的一个一个redo log block,选择有空闲空间的redo log block去写入,然后 redo log block 写满之后,其实会在某个时机刷入到磁盘里去。
  • 1如果写入redo log buffffer的日志已经占据了redo log buffffer总容量的一半了,也就是超过了8MB 的redo log在缓冲里了,此时就会把他们刷入到磁盘文件里去。
  • 2一个事务提交的时候,必须把他的那些redo log所在的redo log block都刷入到磁盘文件里去,只有这样,当事务提交之后,他修改的数据绝对不会丢失,因为redo log里有重做日志,随时可以恢复事 务做的修改。
  • 3后台线程定时刷新,有一个后台线程每隔1秒就会把redo log buffffer里的redo log block刷到磁盘 文件里去
  • 4MySQL关闭的时候,redo log block都会刷入到磁盘里去。
高并发SQL: 如果你瞬间 执行大量的高并发的SQL语句,1秒内就产生了超过8MB的redo log,此时 占据了redo log buffffer一半的空间了,必然会直接把你的redo log刷入磁盘里去
        在MySQL 承载高并发请求的时候比较常见,比如每 秒执行上万个增删改 SQL语句,每个SQL产生的redo log假设有几百个字节, 此时却是会在瞬间生成超过 8MB redo log 日志,必然会触发立马刷新redo log 到磁盘。
事务SQL:  平时执行一个事务,这个 事务一般都是在几十毫秒到几百毫秒执行完毕 ,说实在的,一般正常性能情况下, MySQL 单事务性能一般不会超过 1 秒,否则数据库操作就太慢 了。
那么如果在几十毫秒,或者几百毫秒的时候,执行完毕了一个事务,此时必然会立马把这个事务的 redo log都刷入磁盘。

6、日志文件就用一个写入全部的redo log

        实际上默认情况下,redo log 都会写入一个目录中的文件里,这个目录 可以通过show variables like 'datadir' 来查看,可以通过 innodb_log_group_home_dir 参数来设置这个目录的。
        然后redo log 是有多个的,写满了一个就会写下一个 redo log ,而且可以限制 redo log 文件的数量,通过innodb_log_fifile_size 可以指定每个 redo log 文件的大小,默认是 48MB ,通过
innodb_log_fifiles_in_group 可以指定日志文件的数量,默认就 2 个。
        所以默认情况下,目录里就两个日志文件,分别为ib_logfifile0 ib_logfifile1 ,每个 48MB ,最多就这 2 个 日志文件,就是先写第一个,写满了写第二个。那么如果第二个也写满了呢?别担心,继续写第一个,覆盖第一个日志文件里原来的redo log 就可以了。
        所以最多这个redo log mysql 就给你保留了最近的 96MB redo log 而已,不过这其实已经很多了,毕竟redo log 真的很小,一条通常就几个字节到几十个字节不等, 96MB 足够你存储上百万条 redo log 了!
        如果你还想保留更多的redo log ,其实调节上述两个参数就可以了,比如每个 redo log 文件是 96MB ,最多保留100 redo log 文件。下面图里,给大家展示出来了多个 redo log 文件循环写入的示意。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值