今天有一朋友发了一个参数过来(innodb_flush_log_at_timeout),着实没见过这个参数,从字面意思上理解和刷新日志有关,所以就查了一下,我这里说一下自己的观点:
1.innodb_flush_log_at_timeout 这个参数的意思是刷新日志的时间,在mysql5.6版本中可以自定义,默认为1s。其与oracle有很大区别:
在oracle中,有三种情况可以将日志缓冲区的数据写到在线日志文件中
(1).日志缓冲区中的记录达到1M
(2).每隔3秒
(3).日志缓冲区已经用了三分之一
2.INNODB REDO日志:InnoDB为了保证日志的刷写的高效,使用了内存的log buffer。
由于InnoDB大部分情况下使用的是文件系统,(linux文件系统本身也是有buffer的)而不是直接使用物理块设备,这样的话就有两种丢失日志的可能性:日志保存在log_buffer中,机器挂了,对应的事务数据就丢失了;日志从log buffer刷到了linux文件系统的buffer,机器挂掉了,对应的事务数据就丢失了。
3.InnoDB有一个参数用于设置这两个缓存的刷新: innodb_flush_log_at_trx_commit。而 innodb_flush_log_at_trx_commit 有三个值:0/1/2,默认是1。而innodb_flush_log_at_timeout 定义了每次日志刷新的时间,与 innodb_flush_log_at_trx_commit 配合使用,其具体流程,先看下图:
innodb_flush_log_at_time
innodb_flush_log_at_trx_commit=1,表示在每次事务提交的时候,都把log buffer刷到文件系统中(os buffer)去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。
innodb_flush_log_at_trx_commit=0,表示每隔一秒把log buffer刷到文件系统中(os buffer)去,并且调用文件系统的“flush”操作将缓存刷新到磁盘上去。也就是说一秒之前的日志都保存在日志缓冲区,也就是内存上,如果机器宕掉,可能丢失1秒的事务数据。
innodb_flush_log_at_trx_commit=2,表示在每次事务提交的时候会把log buffer刷到文件系统中(os buffer)去,但是每隔一秒调用文件系统(os buffer)的“flush”操作将缓存刷新到磁盘上去。如果只是MySQL数据库挂掉了,由于文件系统没有问题,那么对应的事务数据并没有丢失。只有在数据库所在的主机操作系统损坏或者突然掉电的情况下,数据库的事务数据可能丢失1秒之类的事务数据。这样的好处,减少了事务数据丢失的概率,而对底层硬件的IO要求也没有那么高(log buffer写到文件系统中,一般只是从log buffer的内存转移的文件系统的内存缓存中,对底层IO没有压力)。MySQL 5.6.6以后,这个“1秒”的刷新还可以用innodb_flush_log_at_timeout 来控制刷新间隔。
结合上面几个参数的描述,我相信多数企业采用mysql innodb存储引擎都是为了充分保证数据的一致性,所以,innodb_flush_log_at_trx_commit这个参数一般都是 1,这样的话,innodb_flush_log_at_timeout 的设置对其就不起作用。innodb_flush_log_at_timeout 的设置只针对 innodb_flush_log_at_trx_commit为0/2 起作用,所以,此参数可暂时不做研究!