内存刷新机制

red log buffer、data buffer、binlog cache。在O和M中,讲究日志先行策略,就是一条DML语句进入数据库之后,都会先写日志,再写数据文件。

1.red log,

重做日志文件,用于记录事务操作的变化,记录的是数据修改之后的值,不管事务是否提交都会记录下来。在实例和介质失败时,重做日志文件就能派上用场,如数据库掉电,InnoDB存储引擎会使用重做日志恢复到掉电前的时刻,以此来保证数据的完整性。

默认情况下至少有两个red log文件,在磁盘上用ib_logfile(0-N)命名。

red log写的方式是顺序和循环写,当写满最后一个文件时,会重新从第一个文件开始写,写满日志文件会产生切换操作,并执行 checkpoint,触发脏页的刷新。MySQL数据库重启过程中,如果参数文件中的red log值大小与当前redo log值不一致,会把现有redo log 删除,并按照参数文件中设置的大小,重新生成新的redo log文件。

(1)在磁盘中生成 red log文件之前,数据是先写在red log buffer中的。

  • 通过innodb_flush_log_at_trx_commit参数来控制。该参数分别为0,1,2
  • 0的含义:red log thread每隔1秒会将red log buffer中的数据写入red log文件,同时进行刷盘操作。保证数据确实写入磁盘。在此参数下,每次事务提交并不会触发red log thread将日志缓冲中的数据写入red log文件。
  • 1的含义:每次事务提交时,都会触发redo log thread将日志缓冲中的数据写入文件,并flush到磁盘。该设置下是最安全的模式。保证数据库在主机断电,OS crash下不会丢失任何已提交的数据。
  • 2的含义:每次事务提交时,都会把redo log buffer的数据写入redo log 文件,但是不会同时刷新到磁盘。

三种模式下:

0性能最好,但是不安全,MySQL进程一旦崩溃会导致丢失一秒的数据。

1是安生性最高,但数据库性能最慢。

2是介于两者之间。

(2)master thread:每秒进行刷新

(3)redo log buffer:使用超过一半的时候会触发刷新。

 

2.binlog

DML语句既会写red log 文件,也会写binlog文件。功能主要用于备份恢复和主从复制。

从binlog cache刷新到磁盘的binlog文件中,需要通过sync_binlog参数来决定。

a.sync_binlog=0,当事务提交之后,MySQL不做fsync之类的磁盘同步指令刷新binlog_cache中的信息来到磁盘,而让Filesystem自行决定什么时候来做同步,或都cache满了之后才同步到磁盘。

b.sync_binlog=N,每进行N次事务提交之后,MySQL将进行一次fsync之类的磁盘同步指令来将binlog_cache中的数据强制写入磁盘。

 

++++++++++++++++++++++++++++++++++red log和binlog区别++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

两都都是记录了对数据真实的修改的语句。同时有以下区别:

1.记录内容的不同。

binlog是逻辑日志,记录所有数据的改变信息。

red log记录的是物理日志,记录所有InnoDB表数据的变化。

 

2.记录内容的时间不同。

binlog 记录commit完毕之后的DML和DDLSQL语句。

red log记录事务发起之后的DML和DDL SQL语句。

3.文件使用方式的不同。

binlog不是循环使用,在写满或者实例重启之后,会生成新的binlog文件。

red log是循环使用,最后一个文件写满之后,会重新写第一个文件。

 

4.作用不同。

binlog可以作为恢复数据使用,主从复制搭建。

red log作为异常宕机中都介质故障后的数据恢复使用。

 

有以下关联:

在主从环境中,从库需要通过二进制日志来应用主库提交的事务,但如果主库red log已经提交而二进制日志没有保持一致,则会造成从库数据丢失,主从数据不一致的情况,见以下分析:

MySQL两阶段提交过程:

a.准备阶段(transaction prepare):事务SQL语句先写入redo log buffer,然后做一个事务准备标记,再将log buffer中的数据刷新到redo log.

b.提交阶段(commit):将事务产生的binlog写入文件,刷入磁盘。

再在redo log中做一个事务提交的标记,并把binlog写成功的标记也一并写入red log文件。

结合以下两场景分析两阶段如何保持数据库的一致性:

Sense one:

准备阶段,redo log刷新到磁盘了,但是binlog写盘前发生了MySQL实例crash,这是会发生怎么的操作呢?

即使redo log写盘成功了,但由于binlog未写入成功,我们需要执行回滚操作来保证数据的一致性。

 

Sense two:

提交阶段,binlog写盘成功了,此时MySQL实例发生crash,此时binlog已经确保写成功了,我们在重启实例进行恢复时,只需要让redo log重做一次就可以了。

总结一下:

其实只要binlog写入完成,则在主从复制环境中,都会正常完成事务。

最后看一下脏页的刷新条件:

(1)重做日志ib_logfile文件写满后,在切换的过程中会执行checkpoint,会触发脏页的刷新。

(2)通过innodb_max_dirty_pages_pct参数的值控制。该参数是指在buffer pool中dirty page所占的百分比,达到设置的值,就会触发脏页的刷新。

(3)由innodb_adaptive_flushing参数控制。

posted @ 2018-09-12 14:58  青空如璃  阅读(1134)  评论(0编辑  收藏  举报