3.6 InnoDB存储引擎后台线程
MySQL是一个单进程多线程架构的数据库管理系统,所以当MySQL实例启动之后,会存在众多的线程来做各种各样的事情。我们可以通过performance_schema.threads表查询到所有线程,包括后台线程和前台线程,这里主要介绍后台线程(前台线程其实就是通过TCP/IP协议或客户端程序创建的线程,所以包括了与主备复制相关的线程和用户创建的连接线程)。
mysql> select name, type, thread_id, processlist_id from performance_schema.threads; +----------------------------------------+-----------+----------+---------------+ | name | type |thread_id | processlist_id| +----------------------------------------+-----------+----------+---------------+ | thread/sql/main |BACKGROUND| 1 | NULL | | thread/sql/thread_timer_notifier |BACKGROUND| 2 | NULL | | thread/innodb/io_ibuf_thread |BACKGROUND| 3 | NULL | | thread/innodb/io_log_thread |BACKGROUND| 4 | NULL | | thread/innodb/io_read_thread |BACKGROUND| 5 | NULL | ...... | thread/innodb/io_write_thread |BACKGROUND| 13 | NULL | ...... | thread/innodb/page_cleaner_thread |BACKGROUND| 29 | NULL | | thread/innodb/srv_lock_timeout_thread |BACKGROUND| 31 | NULL | | thread/innodb/srv_error_monitor_thread |BACKGROUND| 32 | NULL | | thread/innodb/srv_monitor_thread |BACKGROUND| 33 | NULL | | thread/innodb/srv_master_thread |BACKGROUND| 34 | NULL | | thread/innodb/srv_purge_thread |BACKGROUND| 35 | NULL | | thread/innodb/srv_worker_thread |BACKGROUND| 36 | NULL | ...... | thread/innodb/buf_dump_thread |BACKGROUND| 39 | NULL | | thread/innodb/dict_stats_thread |BACKGROUND| 40 | NULL | | thread/sql/signal_handler |BACKGROUND| 41 | NULL | +----------------------------------------+-----------+----------+---------------+ 40 rows in set(0.00 sec)
我们可以看到总共有16种后台线程,这些后台线程的主要功能如下。
● srv_master_thread(主线程):InnoDB存储引擎主线程,由4个循环组成,即主循环(loop)、后台循环(background loop)、刷新循环(flush loop)、暂停循环(suspend loop),其中大多数工作都在主循环中完成,主循环主要负责将脏缓存页刷新到数据文件中,执行undo purge操作,触发检查点,合并插入缓冲区,刷新redo log到磁盘中等。
● io_ibuf_thread(插入缓冲线程):主要负责插入缓冲区的合并操作。将对辅助索引页的修改操作从随机变成顺序I/O,大幅度提升了效率(会先判断发生修改的辅助索引页是否在缓冲池中,如果在则直接修改;如果不在,则先存放在一个Change Buffer对象中。当其他读取操作把该修改对应的页从磁盘读取到缓冲池中时,就会合并该Change Buffer对象中保存的记录到辅助索引页中)。
● io_read_thread(读I/O操作线程):负责数据库的AIO(异步I/O)读取操作,可以配置多个读线程,由参数innodb_read_io_threads设置,默认值为4。
● io_write_thread(写I/O操作线程):负责数据库的AIO写操作,可配置多个写线程,由参数innodb_write_io_threads设置,默认值为4。
● io_log_thread(日志线程):用于将重做日志刷新到日志文件中。
● srv_purge_thread(undo清理线程):主要负责undo页清理操作,在MySQL 5.6之后可设置独立的线程执行undo purge操作,以减少主线程负载。
● srv_lock_timeout_thread(锁线程):负责锁控制和死锁检测等。
● srv_error_monitor_thread(错误监控线程),主要负责错误控制和错误处理。
● page_cleaner_thread(脏页清理线程):负责刷脏操作。在MySQL 5.6之后可设置独立的线程执行刷脏操作,以减少主线程负载。刷脏分为两种方式,其中一种是基于LRU list(最近最少访问的列表)的最近访问时间顺序刷新的;另一种是基于flush list(刷新列表)的最近修改时间和LSN值的顺序刷新的。
● thread_timer_notifier(计时器过期通知线程):超过计时器时间,通知线程处理。一般在超过MAX_EXECUTION_TIME时自动中止SQL语句的执行。
● main(主线程):MySQL服务的主线程(请与InnoDB存储引擎主线程区别开),包括初始化、读取配置文件等功能。
● srv_monitor_thread(InnoDB监控打印线程):如果开启了InnoDB监控器,那么每隔5秒打印一次InnoDB监视器采集的信息。
● srv_worker_thread(InnoDB工作线程):InnoDB的实际工作线程,轮询从任务队列中取出任务(row select、row insert等)并执行。
● buf_dump_thread(InnoDB缓冲池导入/导出线程):InnoDB缓冲池热点数据页导入/导出的线程。
● dict_stats_thread(InnoDB后台统计线程):负责InnoDB表统计信息更新的后台线程。
● signal_handler(信号处理线程):负责SIGTERM、SIGQUIT、SIGHUP信号处理的线程。