MySQL-- InnoDB 线程模型(3)

103 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第30天,点击查看活动详情

image.png 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; 

image.png

  • 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秒操作一次)