前面我们说到了RedoLog也就是当需要去修改一个数据如: update User name="张三" where id=2 从物理结构上说,我们首先是将这行数据所在的表空间找到然后找到数据区最后找到对应的数据页。
总的来说一个表空间内有很多组数据区,一组数据区下有256个数据区,一个数据区下有64个数据页。我们的数据就存储在数据页里。修改时需要加载到buffer-Pool中。
上图是修改的流程我们提交事务的时候会把变更记录写入到redo-log中的。接下来我们要深入分析一下redoLog文件及其流程。
redo-Log作用
我们修改或删除某个数据的时候讲数据页,加载到buffer-Pool中进行了修改提交了事务写入redo-Log中。本质上来说redoLog是为了保证提交事务后数据不丢失。
就算这个时候突然断电我们重启之后,也可以从redoLog中找到变更记录然后恢复到缓存页上最好通过IO线程刷新数据到磁盘。一句好说就是根据redoLog记录在bufferPool重做一遍修改。那redolog日志大致是怎么样的?
日志类型(就是类似MLOG_1BYTE之类的),表空间ID,数据页号,数据页中的偏移量,具体修改的数据
而日志类型根据你修改了数据页里的几个字节的值,redo log就划分为了不同的类型,MLOG_1BYTE类型的日志指的就是修改了1个字节的值,MLOG_2BYTE类型的日志指的就是修改了2个字节的值,以此类推,还有修改了4个字节的值的日志类型,修改了8个字节的值的日志类型。如果你要是一下子修改了一大串的值,类型就是MLOG_WRITE_STRING,就是代表你一下子在那个数据页的某个偏移量的位置插入或者修改了一大串的值。
redo-log block
我们想一下我们是把redoLog日志一条条的写入文件中吗? 其实不是的我们是多个redolog日志放到redo-log block中。一个bolck中有512字节,其中12字节为头,4字节为尾,496字节为块体Body。
在block块的header中分为4个部分
- redolog block的编号 占用4字节。
- 数据长度就是block块中写入了多少数据。占用2字节
- 这个是说每个事务都有多个redolog,这些多个redolog是一个组的。在这里存储的是第一个组的redolog的偏移量。占用2字节
4。checkpoint no 占用4字节
我们真正写入redolog的时候其实是在内存中创建好redolog-block后等待块被我们写满然后再一次性的写入的真正的redolog日志文件中如下图。
redo-log buffer
redologbuffer也是一个内存组件默认大小为16Mb,这片内存空间里也会划分多个redo-log block 。每个512字节,相对于来说已经很大了。上面我们说了当要写入redo日志的时候会先写入内存,然后在刷到磁盘的redolog日志文件中。 看到这个缓冲组件就知道了其实我们的redolog是写入这个redo-log-buffer的。
写满一个redo-log-block 就会接着写第二个redo-log-block。如果是个事务的redolog比较多就会写写两个block,如果很小多个事务的redolog就会占用一个block。
redo-log buffer什么时候写入磁盘
-
如果redolog日志写入的数据量超过了redo-log-buffer缓冲区的一般,也就是8MB就会刷入磁盘。
-
当一个事务提交的时候必须把那个redolog所在的block刷入磁盘,不然提交后突然宕机怎么保证数据重做。
-
后台线程会每隔1秒定时的把数据刷新到磁盘里去。
-
mysql服务关闭的时候也会把缓冲区的数据刷新到磁盘。
其实redo-log日志文件其实是两个,每个大小48M 这样的话我们的redo-log最大保存96MB的数据然后就会覆盖循环写入。通过innodb_log_file_in_group 进行日志文件数量的配置。