赞
踩
我们平时执行完增删改之后,要写入磁盘的redo log,其实应该是先进入redo log block这个数据结构里去的,然后在进入磁盘文件里:
也就是说redo log先通过内存缓存之后,再进入到磁盘文件里去的。这里涉及到了一个新的组件,redo log buffer
,它是MySQL专门涉及用来缓存redo log写入的。
这个redo log buffer其实就是MySQL在启动的时候,跟操作系统申请的一块连续内存空间,和buffer pool(申请之后划分了N个空的缓存页和一些链表结构,让你把磁盘上的数据加载到内存里来)的作用类似,它申请之后划分了N个空的redo log block。redo log buffer结构如下图:
通过设置MySQL的innodb_log_buffer_size
可以指定这个redo log buffer的大小,默认是16MB,其实已经够大了,因为一个redo log block才512字节而已,每一个redo log也不过几个字节到几十个字节罢了。
redo log都是先写入到内存里的redo log block数据结构里,然后block满了之后才会把redo log block写入到磁盘文件里去,而不是直接把redo log写入磁盘。
如下图,表示在磁盘文件里不停的追加一个又一个的redo block:
在我们平时执行一个事务的过程中:
redo log在写的时候,都是一组事务里的一组redo log,先暂存在一个地方,完事之后把一组redo log写入redo log buffer。
写入redo log buffer的时候,是写入里面提前划分好的一个一个的redo log block机制的,选择有空闲空间的redo log block去写入,等redo log block写满之后,会在某个时机刷入磁盘里去。
问题: redo log block是哪些时候会刷入到磁盘里去?
(1)如果写入redo log buffer的日志已经占据了redo log buffer总容量的一半了,也就是超过了8MB的redo log在缓冲里了,此时就会把它们刷入到磁盘里去。
(2)一个事务提交的时候,必须把它的那些redo log block都刷入到磁盘文件里去,只有这样,当事务提交之后,它修改的数据绝对不会丢失,因为redo log里有重做日志,随时可以恢复事务做的修改(注意redo log哪怕事务提交的时候写入磁盘文件,也是先进入 os cache的,进入 os的文件缓冲区里,所以是否提交事务就强行把 redo log刷入物理磁盘文件中,这个需要设置对应的参数)
innodb_flush_log_at_trx_commit
配置来控制redo log的写盘时机。
(3)后台线程定时刷新,有一个后台线程每隔1s就会把redo log buffer里的redo log block刷到磁盘文件里去。
(4)MySQL关闭的是,redo log block都会刷入到磁盘里去
问题:我们平时不停的执行增删改,那么MySQL会不停的产生大量的redo log写入日志文件,那么日志文件就用一个写入全部的redo log吗?对磁盘占用空间越来越大怎么办?
默认情况下,redo log都会写入一个目录中的文件,这个目录可以通过show variables like 'datadir'
来看:
innodb_log_group_home_dir
参数来设置这个目录。然后redo log是有多个的,写满了一个就会写下一个redo log,而且可以限制redo log文件的数量:
innodb_log_file_size
可以指定每个redo log文件的大小,默认48MBinnodb_log_files_in_group
可以指定日志文件的数量,默认2个所以默认情况下,目录里就两个日志文件,分别为ib_logfile0和ib_logfile1,每个48MB,最多就这2个日志文件,就是先写第一个,写满了写第二个。那么如果第二个也写满了呢?别担心,继续写第一个,覆盖第一个日志文件里原来的redo log就可以了。
所以最多MySQL保留了最近96MB的redo log,不过这其实已经很多了,毕竟redo log很小,一条通常也就几个字节到几十个字节不等,96MB就足够存储上百万条redo log了。
如果你还想保留更多的redo log,其实调节上述两个参数就可以了,比如每个redo log文件是96MB,最多保留100个redo log文件。下面图里,展示出来了多个redo log文件循环写入的示意。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。