innodb二等第日志提交机制和组提交分析,innodb日

作者: 数据库信息  发布:2019-09-05

前些天在查看关于innodb_flush_log_at_trx_commit的官网解释时产生了一些疑问,关于innodb_flush_log_at_trx_commit参数的详细解释参见官网:

innodb二阶段日志提交机制,innodb日志提交

前些天在查看关于innodb_flush_log_at_trx_commit的官网解释时产生了一些疑问,关于innodb_flush_log_at_trx_commit参数的详细解释参见官网:

其中有一段是这么写的: With a value of 2, the contents of the InnoDB log buffer are written to the log file after each transaction commit and the log file is flushed to disk approximately once per second. 意思是:如果innodb_flush_log_at_trx_commit的值设为2,那么log buffer里的内容会在每次提交时被写入log file,然后logfile也会被flush到disk。 由于innodb的log file据我所知是在硬盘上的ib_logfile,所以对于这里的log file被flush到disk很疑惑,难道log buffer和disk之间还存在了一层可以缓存log file的结构?   在查阅了大量中英文资料后,总算有了初步的了解,暂总结于此。   一、名词解释 在innodb存储引擎中,有一种独有的log file,即redo log file,因此对于innodb存储引擎来说,就存在两种logfile:redo log和binlog. redo log:即data目录下的ib_logfile0,ib_logfile1(个数由innodb_log_files_in_group控制),innodb存储引擎特有,在内存中有相应的redo log buffer。 因此写redo时的3层结构为:redo log buffer--->文件系统缓存中的redo logfile--->disk上的redo log file binlog:默认在data目录下,也可以通过log_bin参数直接指定路径,文件名为默认为<hostname>-bin前缀的文件,在内存中没有log buffer。 因此写binlog时的2层结构为:文件系统缓存中的binlog--->disk上的binlog   二、二阶段日志写的流程 原图来自: 澳门金莎娱乐网站 1 当开启binlog后,如果会话发出了commit的请求,那么在committed之前,一系列的流程为: 1.prepare阶段: 将log buffer的事务更改和事务commit信息写入文件系统缓存中的redo log file,注意log buffer和undo buffer(也叫undo page)是在事务执行过程中就即时生成的(undo默认在系统表空间中,5.6以后也可以自己指定独立的表空间),文件系统缓存中的redo log 是否flush到disk,取决于innodb_flush_log_at_trx_commit参数。 innodb_flush_log_at_trx_commit:

  • 此值为0表示:redo log buffer的内容每秒会被写入文件系统缓存的redo log里,同时被flush(固化)到disk上的redo log file中。
  • 此值为1表示:redo log buffer的内容会在事务commit时被写入文件系统缓存的redo log里,同时被flush(固化)到disk上的redo log file中。

  • 此值为2表示:redo log buffer的内容会在事务commit时被写入文件系统缓存的redo log里,而文件系统缓存的redo log每秒一次被flush(固化)到disk上的redo log file中。

2.写binlog阶段: 此阶段调用两个方法write()和fsync(),前者负责写文件系统缓存中的binlog,后者负责将文件系统缓存中的binlog写入disk上的bin log,前者在此阶段一定会被调用,后者的调用机制由sync_binlog参数控制。 关于sync_binlog参数:

  • sync_澳门金莎娱乐网站 ,binlog=0:表示fsync()的调用完全交给操作系统,即文件系统缓存中的binlog是否刷新到disk完全由操作系统控制。

  • sync_binlog=1:表示在事务提交时,binlog一定会被固化到disk

  • sync_binlog=N(N>1):数据库崩溃时,可能会丢失N-1个事务,具体原理也详见

3.最终commit阶段: 此阶段主要包含:server告诉存储引擎,binlog和redo log都已写好(至少在文件系统缓存级别已经写好),按正常机制提交数据吧,然后向会话返回committed的确认提交信息。   三、故障恢复解析 1.如果在一阶段后崩溃,那么由于binlog未写,数据显然未能提交,算是失败的事务,无需前滚或回滚。(对于oracle数据库则情况更为复杂,有些大事务即便未提交也可能有已经固化的数据,那么就需要进行回滚。还不清楚mysql的大事务是否也有未提交数据提前写入disk的机制) 2.如果在二阶段后崩溃,那么只有一种情况可以保证数据完全不丢失,即:innodb_flush_log_at_trx_commit和sync_binlog都设置为1,此时redo log和binlog都被固化到磁盘,可以保证commit后未写入的数据在recovery时被前滚提交。如果任意一个不为1,那么都可能造成binlog和redo log不一致的情况,此时很可能丢失事务。 因此,为保证主从完全一致,主库的innodb_flush_log_at_trx_commit和sync_binlog都必须设置为1。   至于5.6以后的为解决并发事务提交异常而出现的3阶段组提交机制,有待继续研究。

 

前些天在查看关于 innodb_flush_log_at_trx_commit的官网解释时产生了一些疑问,关于 innodb_flush_log_at_t...

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

其中有一段是这么写的:

With a value of 2, the contents of the InnoDB log buffer are written to the log file after each transaction commit and the log file is flushed to disk approximately once per second.

意思是:如果innodb_flush_log_at_trx_commit的值设为2,那么log buffer里的内容会在每次提交时被写入redo log file,然后redo log file每秒被flush到disk。

由于innodb的redo log file据我所知是在硬盘上的ib_logfile,所以对于这里的log file被flush到disk很疑惑,难道log buffer和disk之间还存在了一层可以缓存log file的结构?

 

在查阅了大量中英文资料后,总算有了初步的了解,暂总结于此。

 

一、名词解释

在innodb存储引擎中,有一种独有的log file,即redo log file,因此对于innodb存储引擎来说,就存在两种logfile:redo log和binlog.

redo log:即data目录下的ib_logfile0,ib_logfile1(个数由innodb_log_files_in_group控制),innodb存储引擎特有,在内存中有相应的redo log buffer。

因此写redo时的3层结构为:redo log buffer--->文件系统缓存中的redo logfile--->disk上的redo log file

binlog:默认在data目录下,也可以通过log_bin参数直接指定路径,文件名为默认为<hostname>-bin前缀的文件,在内存中没有log buffer。

因此写binlog时的2层结构为:文件系统缓存中的binlog--->disk上的binlog

好尴尬,Oracle通常是绕过文件系统缓存来直接写入磁盘的,对Mysql的这种机制还不太了解。

 

二、二阶段日志写的流程

原图来自: (个人认为此站作者对于这幅图的理解有误,以下为查阅资料后的个人解释)

澳门金莎娱乐网站 2

当开启binlog后,如果会话发出了commit的请求,那么在committed之前,一系列的流程为:

1.prepare阶段:

此阶段负责将log buffer的redo日志和undo写入文件系统缓存中的redo log和undo以及写入disk上的redo log和undo,写入机制取决于innodb_flush_log_at_trx_commit参数。

innodb_flush_log_at_trx_commit:(默认值为1)

  • 此值为0表示:redo log buffer的内容每秒会被写入文件系统缓存的redo log里,同时被flush(固化)到disk上的redo log file中。

  • 此值为1表示:redo log buffer的内容会在事务commit时被写入文件系统缓存的redo log里,同时被flush(固化)到disk上的redo log file中。

  • 此值为2表示:redo log buffer的内容会在事务commit时被写入文件系统缓存的redo log里,而文件系统缓存的redo log每秒一次被flush(固化)到disk上的redo log file中。

注意log buffer和undo buffer(也叫undo page)是在事务执行过程中就即时生成的(undo的disk文件位置默认在系统表空间中,5.6以后也可以自己指定独立的表空间),

2.写binlog阶段:

此阶段调用两个方法write()和fsync(),前者负责写文件系统缓存中的binlog,后者负责将文件系统缓存中的binlog写入disk上的bin log,前者在整个事务执行过程中都会被一直调用,后者的调用机制由sync_binlog参数控制。

关于sync_binlog参数:

  • sync_binlog=0:表示fsync()的调用完全交给操作系统,即文件系统缓存中的binlog是否刷新到disk完全由操作系统控制。

  • sync_binlog=1:表示在事务提交时,binlog一定会被固化到disk

  • sync_binlog=N(N>1):数据库崩溃时,可能会丢失N-1个事务,具体原理也详见https://jin-yang.github.io/post/mysql-group-commit.html

3.innodb引擎内部提交阶段:

Innodb完成事务提交,清除undo信息,将事务设置为TRX_NOT_STARTED状态。

Innodb进行crash recovery时是根据binlog来进行前滚回滚的。只有记录了binlog才会根据redo log前滚或回滚事务。

 

三、故障恢复解析

1.如果在一阶段后崩溃,binlog未写,innodb引擎层直接回滚事务。

2.如果在二阶段后崩溃,binlog已写,那么server告诉innodb重做事务,事务不丢失。

本文由金沙澳门官网发布于数据库信息,转载请注明出处:innodb二等第日志提交机制和组提交分析,innodb日

关键词: 金沙澳门官网

上一篇:MyCAT详解
下一篇:没有了