持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情
InnoDB存储引擎是多线程的模型,因此其后台有多个不同的后台线程,负责处理不同的任务.
后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下InnoDB能恢复到正常运行状态。
1. IO Thread
在InnoDB中使用了大量的AIO(Async IO)来做读写处理,这样可以极大提高数据库的性能。在InnoDB1.0版本之前共有4个IO Thread,分别是write,read,insert buffer和log thread,后来版本将read thread和write thread分别增大到了4个,一共有10个了。
show engine innodb status;
- read thread : 负责读取操作,将数据从磁盘加载到缓存page页。4个
- write thread:负责写操作,将缓存脏页刷新到磁盘。4个
- log thread:负责将日志缓冲区内容刷新到磁盘。1个
- insert buffer thread :负责将写缓冲内容刷新到磁盘。1个
2. Purge Thread
事务提交之后,其使用的undo日志将不再需要,因此需要Purge Thread回收已经分配的undo页。
mysql> show variables like '%innodb_purge_threads%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_purge_threads | 4 |
+----------------------+-------+
1 row in set (0.01 sec)
InnoDB1.2+开始,支持多个Purge Thread 这样做的目的为了加快回收undo页(释放内存)。
3. Page Cleaner Thread
作用是将脏数据刷新到磁盘,脏数据刷盘后相应的redo log也就可以覆盖,即可以同步数据,又能达到redo log循环使用的目的。会调用write thread线程处理。
mysql> show variables like '%innodb_page_cleaners%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_page_cleaners | 1 |
+----------------------+-------+
4. Master Thread
Master thread是InnoDB的主线程,负责调度其他各线程,优先级最高。作用是将缓冲池中的数据异步刷新到磁盘 ,保证数据的一致性。包含:脏页的刷新(page cleaner thread)、undo页回收(purge thread)、redo日志刷新(log thread)、合并写缓冲等。内部有两个主处理,分别是每隔1秒和10秒处理。
每1秒的操作:
-
刷新脏页数据到磁盘,根据脏页比例达到75%才操作
innodb_io_capacity用来表示IO的吞吐量,默认200,对于刷新到磁盘页的数量,会按照innodb_io_capacity的百分比来控制:
-
在从缓冲池刷新脏页时,刷新脏页的数量为innodb_io_capcity;
mysql> show variables like 'innodb_io_capacity'; +--------------------+-------+ | Variable_name | Value | +--------------------+-------+ | innodb_io_capacity | 200 | +--------------------+-------+ 1 row in set (0.00 sec) -
如果缓冲池中的脏页比例大于innodb_max_dirty_pages_pct(默认是75%时),刷新脏页到磁盘 数量是innodb_io_capacity的值
mysql> show variables like 'innodb_max_dirty_pages_pct'; +----------------------------+-----------+ | Variable_name | Value | +----------------------------+-----------+ | innodb_max_dirty_pages_pct | 75.000000 | +----------------------------+-----------+
-
-
合并写缓冲区数据: 并不是每秒刷新的,如果前一秒的IO次数小于5,则认为IO压力小,可以执行合并插入缓冲的操作。
-
刷新日志缓冲区到磁盘:即使事务没有提交,InnoDB也会每秒将重做日志缓冲刷新到重做日志文件中,因此可以理解为什么再大的事务提交,时间也是很短的。
每10秒的操作:
-
刷新脏页数据到磁盘
- 从缓冲池刷新脏页时,刷行脏页的数量为innodb_io_capcity;
-
合并写缓冲区数据
- 每隔10秒, 合并插入缓冲是innodb_io_capacity的5%
-
刷新日志缓冲区(每隔10秒操作一次)
-
删除无用的undo页(每隔10秒操作一次)