MySQL innodb引擎的事务执行过程(3)

即脏页的数量太多,导致InnoDB存储引擎强制进行Checkpoint。其目的总的来说还是为了保证缓冲池中有足够可用的页。其可由参数innodb_max_dirty_pages_pct控制:

mysql> SHOW GLOBAL VARIABLES LIKE 'innodb_max_dirty_pages_pct' ;

+----------------------------+-------+

| Variable_name | Value |

+----------------------------+-------+

| innodb_max_dirty_pages_pct | 75 |

+----------------------------+-------+

innodb_max_dirty_pages_pct值为75表示,当缓冲池中���页的数量占据75%时,强制进行Checkpoint,刷新一部分的脏页到磁盘。在InnoDB 1.0.x版本之前,该参数默认值为90,之后的版本都为75,其可以通过参数innodb_max_dirty_pages_pct来设置;

总结下redo刷新的条件(因为刷新innodb_buffer_pool中的脏数据之前需要刷新redo,所以触发刷新buffer_pool会同时触发刷新redo):

1)当redo log buffer达到一定比值后,

2)刷新innodb_buffer_pool中的脏数据之前,

3)redo log buffer满的时候,没有可用buffer;

4)每秒刷新一次;

5)commit的时候;

6)数据库关闭时发生harp Checkpoint,触发将所有脏页刷回磁盘

7)手工flush logs;

8)重做日志不可用时,触发刷新innodb_buffer_pool中的脏数据,进而触发redo刷新;

三:MySQL binlog: 主从同步 主库binlog先写入到 binlog_buffer中,然后刷新到磁层磁盘也就是binlog文件,主库dump进程读取的binlog文件,发送给从库;

binlog日志是针对整个MySQL server而言的,前面介绍的redo和undo是针对innodb引擎而言的,binlog的存在就是方便那些不支持事务的引擎表来同步数据到slave;

那么到底是先刷新redo还是先写binlog呢?

伴随着这个问题,我重点说下,MySQL innodb 引擎事务commit的过程:

MySQL为了保证master和slave的数据一致性,就必须保证binlog和InnoDB redo日志的一致性,为此MySQL引入二阶段提交(two phase commit or 2pc),MySQL通过两阶段提交(内部XA的两阶段提交)很好地解决了这一问题,两阶段提交关键在于保证redo刷盘之后才能刷新binlog到底层文件,以 binlog 的写入与否作为事务提交成功与否的标志,最后判断 binlog中是否有 redo里的xid,MySQL5.6以前,为了保证数据库上层二进制日志的写入顺序和InnoDB层的事务提交顺序一致,MySQL数据库内部使用了prepare_commit_mutex锁。但是持有这把锁之后,会导致组提交失败;直到MySQL5.6之后,才解决了这个问题,借助序列来保证binlog刷新也可以组提交;关于redo 和binlog组提交,请看下一篇文章,

事务崩溃恢复过程如下:

1.崩溃恢复时,扫描最后一个Binlog文件,提取其中的xid;

2.InnoDB维持了状态为Prepare的事务链表(commit两阶段提交中的第一阶段,为Prepare阶段,会把事务设置为Prepare状态)将这些事务的xid和Binlog中记录的xid做比较,如果在Binlog中存在,则提交,否则回滚事务。

通过这种方式,可以让InnoDB redo 和Binlog中的事务状态保持一致。

四:简单介绍下MySQL的后台进程:

InnoDB存储引擎是多线程模型,因此其后台有多个不同的后台线程,负责处理不同的任务:

1)Master Thread

Master Thread是一个非常核心的后台线程,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性。

2)IO Thread

InnoDB存储引擎中大量使用了Async IO来处理写IO请求,这样可以极大提高数据库的性能,而IO Thread的主要工作是负责这些IO请求的回调处理,可以使用show engine innodb status命令查看InnoDB存储引擎中的IO进程:

mysql> show engine innodb status\g;

I/O thread 0 state: waiting for completed aio requests (insert buffer thread)

I/O thread 1 state: waiting for completed aio requests (log thread)

I/O thread 2 state: waiting for completed aio requests (read thread)

I/O thread 3 state: waiting for completed aio requests (read thread)

I/O thread 4 state: waiting for completed aio requests (read thread)

I/O thread 5 state: waiting for completed aio requests (read thread)

I/O thread 6 state: waiting for completed aio requests (read thread)

I/O thread 7 state: waiting for completed aio requests (read thread)

I/O thread 8 state: waiting for completed aio requests (write thread)

I/O thread 9 state: waiting for completed aio requests (write thread)

I/O thread 10 state: waiting for completed aio requests (write thread)

I/O thread 11 state: waiting for completed aio requests (write thread)

Pending normal aio reads: [0, 0, 0, 0] , aio writes: [0, 0, 0, 0] ,

ibuf aio reads:, log i/o’s:, sync i/o’s:

Pending flushes (fsync) log: 0; buffer pool: 0

451 OS file reads, 54 OS file writes, 7 OS fsyncs

3.77 reads/s, 16384 avg bytes/read, 1.05 writes/s, 0.13 fsyncs/s

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/b6db750bdabd0b498dd92a0eb0c37a91.html