searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

MySQL源码学习——InnoDB线程介绍

2024-09-10 09:23:35
27
0

mysql8.0.20 Innodb引擎共有34种线程(具体可参考ha_innodb.cc的全局线程组all_innodb_threads),分别为

  1. master线程 (srv_master_thread)
  2. Error monitor线程 (srv_error_monitor_thread)
  3. Monitor线程 (srv_monitor_thread)
  4. redo log closed线程 (log_closer)
  5. checkpointer线程 (log_checkpointer)
  6. redo write线程 (log_writer)
  7. redo flush线程 (log_flusher)
  8. redo write 通知线程 (log_write_notifier)
  9. redo flush 通知线程 (log_flush_notifier)
  10. bp dump线程 (buf_dump_thread)
  11. bp resize线程 (buf_resize_thread)
  12. 表信息统计计算线程 dict_stats_thread
  13. 锁监控线程 lock_wait_timeout_thread
  14. alter表空间加解密回滚线程 fsp_init_resume_alter_encrypt_tablespace srv_ts_alter_encrypt_thread
  15. 奔溃恢复事务回滚线程 trx_recovery_rollback_thread
  16. 通知刷脏线程 recv_writer_thread
  17. purge协调线程 srv_purge_coordinator_thread
  18. purge工作线程组 srv_worker_thread
  19. 刷脏工作协调线程 buf_flush_page_coordinator_thread
  20. 刷脏工作线程组 buf_flush_page_cleaner_thread
  21. 日志归档线程 log_archiver_thread
  22. 写redo log归档线程 meb::redo_log_archive_consumer_thread
  23. 内存page归档线程 page_archiver_thread
  24. gtid持久化线程 clone_gtid_thread
  25. 全文索引优化线程 fts_optimize_thread
  26. 并行merge线程 fts_parallel_merge_thread
  27. 并行tokenization线程 fts_parallel_tokenization_thread
  28. io_ibuf_thread
  29. io_log_thread
  30. io_read_thread
  31. io_write_thread
  32. 并行查询生成者线程 parallel_read_thread
  33. 并行查询消费者线程 parallel_read_ahead_thread
  34. clone_ddl_thread 暂时未用到

具体分为分为下面几大类:

1 主线程 master

Master thread优先级最高, 其内部包含几个循环:主循环(loop)、后台循环(background loop)、暂停循环(suspend loop).master thread会根据其内部运行的相关状态在前述各循环间中进行切换.大部分操作在主循环(loop)中完成,Innodb1.2.X后都是1s循环,不在有10s循环:

  • 1s操作分活跃、空闲两种操作,这两种操作主要包括:
    • 日志缓冲刷新到磁盘(必做) 即使某个事务还没有提交,InnoDB仍然每秒会将redo log缓冲中的内容刷新到文件。这可以很好地解释为什么再大的事务提交(commit)的时间也是很短的,具体操作可参考函数log_free_check
    • 惰性删除表(可能) 当alter table请求发生在unix上,当表上没有查询请求时可删除表信息,参考函数srv_master_do_active_tasks
    • 合并change buffer(可能),参考函数ibuf_merge_in_background
    • 清除table中无用的的表(可能) srv_master_evict_from_table_cache

上面三种可能的操作在mysql8.0.20中,活跃操作对应处理函数为srv_master_do_active_tasks、空闲操作对应函数srv_master_do_idle_tasks。

2 监控线程

  • Monitor线程(m_monitor) 5s loop循环,每隔15s打印Innodb各种监控信息(若配置)
  • Error monitor线程 (m_error_monitor)错误、告警监控线程

3 Redo log 相关线程

  • redo log closed线程 (m_log_closer)
  • checkpointer线程 (m_log_checkpointer)
  • redo write线程 (m_log_writer)
  • redo flush线程 (m_log_flusher)
  • redo write 通知线程 (m_log_write_notifier)
  • redo flush 通知线程 (m_log_flush_notifier)

4 buf pool相关线程

  • bp dump线程 (buf_dump_thread)用户线程触发bp内存数据导入导出,在ddl recover完成后才启动该线程,参考函数srv_start_threads_after_ddl_recovery
  • bp resize线程 buf_resize_thread 用户线程触发resize bp,修改bp大小

5 表信息统计线程

表信息统计计算线程(m_dict_stats) 用于重新计算表或索引的统计信息,在一个loop中,等待事件dict_stats_event,或者每隔10秒被无条件唤醒。实际工作函数为dict_stats_process_entry_from_recalc_pool(),涉及全局变量dict_sys、及表操作

6 锁相关线程

mysql锁监控线程 lock_wait_timeout_thread

7 奔溃恢复临时线程

  • alter表空间加解密回滚线程 (fsp_init_resume_alter_encrypt_tablespace)在ddl奔溃恢复完成后启动,执行完成退出
  • 奔溃恢复事务回滚线程 (m_trx_recovery_rollback)
  • 通知刷脏线程(m_recv_writer) 和page cleaner线程配合使用,它会去通知page cleaner线程去flush崩溃恢复产生的脏页,直到recv_sys中存储的redo记录都被应用完成并彻底释放掉(recv_sys->heap == NULL)

8 purge相关线程

DDL恢复完成后启动,参考函数srv_start_threads_after_ddl_recovery

  • purge协调线程(srv_purge_coordinator_thread)
  • purge工作线程组 (srv_worker_thread)

9 page clean相关线程

page clean线程分为下面两种:

  • 刷脏协调线程(buf_flush_page_coordinator_thread)
  • 刷脏工作线程组 (buf_flush_page_cleaner_thread)

buf_flush_page_coordinator_thread协调线程的主循环主线程以最多1s的间隔或者收到buf_flush_event事件就会触发进行一轮的刷脏。刷脏方式分三种,同步刷脏、活跃刷脏和空闲刷脏,其中空闲刷脏只有协调线程进行刷脏操作,不会唤醒work线程。

协调线程非空闲刷脏,首先会调用pc_request()函数,这个函数的作用就是为每个slot代表的缓冲池实例计算要刷脏多少页,然后把每个slot的state设置PAGE_CLEANER_STATE_REQUESTED, 唤醒等待的工作线程。由于协调线程也会和工作线程一样做具体的刷脏操作,所以它在唤醒工作线程之后,会调用pc_flush_slot(),和其它的工作线程并行去做刷脏页操作。一但它做完自己的刷脏操作,就会调用pc_wait_finished()等待所有的工作线程完成刷脏操作。完成这一轮的刷脏之后,协调线程会收集一些统计信息,比如这轮刷脏所用的时间,以及对LRU和flush_list队列刷脏的页数等。然后会根据当前的负载计算应该sleep的时间、以及下次刷脏的页数,为下一轮的刷脏做准备。

10 mysql clone相关线程

  • 日志归档线程(m_log_archiver) 归档有效的redo 日志,与redo_log_archive_consumer用于redo log 归档功能 , MySQL8.0.17中引入了redo log的归档功能,如果开启归档功能,redo log会持续不断的生成,而不会覆盖掉之前的redo log
  • 写redo log归档线程 redo_log_archive_consumer
  • 内存page归档线程 (m_page_archiver)

11 GTID持久化线程 (m_gtid_persister)

在ddl recover完成后启动,参考函数srv_start_threads_after_ddl_recovery,进行gtid持久化操作

12 全文索引相关线程

  • 全文索引优化线程 (m_fts_optimize) 读取队列fts_optimize_wq消息,对全文索引表进行优化
  • 并行merge线程 fts_parallel_merge_thread,创建索引若存在全文索引时会调用执行
  • 并行tokenization线程 fts_parallel_tokenization_thread 全文的读取或排序时会执行调用

13 IO 线程

  • io_ibuf_thread change buffer thread负责把改变缓冲(change buffer)中的内容刷新到磁盘
  • io_log_thread redo log thread负责把日志缓冲中的内容刷新到redo log文件中
  • io_read_thread read thread为mysql的读线程,默认为4个,其负责将数据页从磁盘上读入,其由innodb_read_io_threads选项控制.用户线程发起读请求并将其放至读请求队列,read threads从读请求队列获取读任务并完成.
  • io_write_thread write thread为mysql的写线程,默认为4个,其负责将数据页从缓冲区写出到磁盘,其由innodb_write_io_threads控制选项控制.page_cleaner线程发起写请求并将其放至写请求队列,write threads从写请求队列获取写任务并完成.

14 并行查询线程

  • 并行查询生成者线程 parallel_read_thread
  • 并行查询消费者线程 parallel_read_ahead_thread
0条评论
0 / 1000
dean
4文章数
1粉丝数
dean
4 文章 | 1 粉丝
原创

MySQL源码学习——InnoDB线程介绍

2024-09-10 09:23:35
27
0

mysql8.0.20 Innodb引擎共有34种线程(具体可参考ha_innodb.cc的全局线程组all_innodb_threads),分别为

  1. master线程 (srv_master_thread)
  2. Error monitor线程 (srv_error_monitor_thread)
  3. Monitor线程 (srv_monitor_thread)
  4. redo log closed线程 (log_closer)
  5. checkpointer线程 (log_checkpointer)
  6. redo write线程 (log_writer)
  7. redo flush线程 (log_flusher)
  8. redo write 通知线程 (log_write_notifier)
  9. redo flush 通知线程 (log_flush_notifier)
  10. bp dump线程 (buf_dump_thread)
  11. bp resize线程 (buf_resize_thread)
  12. 表信息统计计算线程 dict_stats_thread
  13. 锁监控线程 lock_wait_timeout_thread
  14. alter表空间加解密回滚线程 fsp_init_resume_alter_encrypt_tablespace srv_ts_alter_encrypt_thread
  15. 奔溃恢复事务回滚线程 trx_recovery_rollback_thread
  16. 通知刷脏线程 recv_writer_thread
  17. purge协调线程 srv_purge_coordinator_thread
  18. purge工作线程组 srv_worker_thread
  19. 刷脏工作协调线程 buf_flush_page_coordinator_thread
  20. 刷脏工作线程组 buf_flush_page_cleaner_thread
  21. 日志归档线程 log_archiver_thread
  22. 写redo log归档线程 meb::redo_log_archive_consumer_thread
  23. 内存page归档线程 page_archiver_thread
  24. gtid持久化线程 clone_gtid_thread
  25. 全文索引优化线程 fts_optimize_thread
  26. 并行merge线程 fts_parallel_merge_thread
  27. 并行tokenization线程 fts_parallel_tokenization_thread
  28. io_ibuf_thread
  29. io_log_thread
  30. io_read_thread
  31. io_write_thread
  32. 并行查询生成者线程 parallel_read_thread
  33. 并行查询消费者线程 parallel_read_ahead_thread
  34. clone_ddl_thread 暂时未用到

具体分为分为下面几大类:

1 主线程 master

Master thread优先级最高, 其内部包含几个循环:主循环(loop)、后台循环(background loop)、暂停循环(suspend loop).master thread会根据其内部运行的相关状态在前述各循环间中进行切换.大部分操作在主循环(loop)中完成,Innodb1.2.X后都是1s循环,不在有10s循环:

  • 1s操作分活跃、空闲两种操作,这两种操作主要包括:
    • 日志缓冲刷新到磁盘(必做) 即使某个事务还没有提交,InnoDB仍然每秒会将redo log缓冲中的内容刷新到文件。这可以很好地解释为什么再大的事务提交(commit)的时间也是很短的,具体操作可参考函数log_free_check
    • 惰性删除表(可能) 当alter table请求发生在unix上,当表上没有查询请求时可删除表信息,参考函数srv_master_do_active_tasks
    • 合并change buffer(可能),参考函数ibuf_merge_in_background
    • 清除table中无用的的表(可能) srv_master_evict_from_table_cache

上面三种可能的操作在mysql8.0.20中,活跃操作对应处理函数为srv_master_do_active_tasks、空闲操作对应函数srv_master_do_idle_tasks。

2 监控线程

  • Monitor线程(m_monitor) 5s loop循环,每隔15s打印Innodb各种监控信息(若配置)
  • Error monitor线程 (m_error_monitor)错误、告警监控线程

3 Redo log 相关线程

  • redo log closed线程 (m_log_closer)
  • checkpointer线程 (m_log_checkpointer)
  • redo write线程 (m_log_writer)
  • redo flush线程 (m_log_flusher)
  • redo write 通知线程 (m_log_write_notifier)
  • redo flush 通知线程 (m_log_flush_notifier)

4 buf pool相关线程

  • bp dump线程 (buf_dump_thread)用户线程触发bp内存数据导入导出,在ddl recover完成后才启动该线程,参考函数srv_start_threads_after_ddl_recovery
  • bp resize线程 buf_resize_thread 用户线程触发resize bp,修改bp大小

5 表信息统计线程

表信息统计计算线程(m_dict_stats) 用于重新计算表或索引的统计信息,在一个loop中,等待事件dict_stats_event,或者每隔10秒被无条件唤醒。实际工作函数为dict_stats_process_entry_from_recalc_pool(),涉及全局变量dict_sys、及表操作

6 锁相关线程

mysql锁监控线程 lock_wait_timeout_thread

7 奔溃恢复临时线程

  • alter表空间加解密回滚线程 (fsp_init_resume_alter_encrypt_tablespace)在ddl奔溃恢复完成后启动,执行完成退出
  • 奔溃恢复事务回滚线程 (m_trx_recovery_rollback)
  • 通知刷脏线程(m_recv_writer) 和page cleaner线程配合使用,它会去通知page cleaner线程去flush崩溃恢复产生的脏页,直到recv_sys中存储的redo记录都被应用完成并彻底释放掉(recv_sys->heap == NULL)

8 purge相关线程

DDL恢复完成后启动,参考函数srv_start_threads_after_ddl_recovery

  • purge协调线程(srv_purge_coordinator_thread)
  • purge工作线程组 (srv_worker_thread)

9 page clean相关线程

page clean线程分为下面两种:

  • 刷脏协调线程(buf_flush_page_coordinator_thread)
  • 刷脏工作线程组 (buf_flush_page_cleaner_thread)

buf_flush_page_coordinator_thread协调线程的主循环主线程以最多1s的间隔或者收到buf_flush_event事件就会触发进行一轮的刷脏。刷脏方式分三种,同步刷脏、活跃刷脏和空闲刷脏,其中空闲刷脏只有协调线程进行刷脏操作,不会唤醒work线程。

协调线程非空闲刷脏,首先会调用pc_request()函数,这个函数的作用就是为每个slot代表的缓冲池实例计算要刷脏多少页,然后把每个slot的state设置PAGE_CLEANER_STATE_REQUESTED, 唤醒等待的工作线程。由于协调线程也会和工作线程一样做具体的刷脏操作,所以它在唤醒工作线程之后,会调用pc_flush_slot(),和其它的工作线程并行去做刷脏页操作。一但它做完自己的刷脏操作,就会调用pc_wait_finished()等待所有的工作线程完成刷脏操作。完成这一轮的刷脏之后,协调线程会收集一些统计信息,比如这轮刷脏所用的时间,以及对LRU和flush_list队列刷脏的页数等。然后会根据当前的负载计算应该sleep的时间、以及下次刷脏的页数,为下一轮的刷脏做准备。

10 mysql clone相关线程

  • 日志归档线程(m_log_archiver) 归档有效的redo 日志,与redo_log_archive_consumer用于redo log 归档功能 , MySQL8.0.17中引入了redo log的归档功能,如果开启归档功能,redo log会持续不断的生成,而不会覆盖掉之前的redo log
  • 写redo log归档线程 redo_log_archive_consumer
  • 内存page归档线程 (m_page_archiver)

11 GTID持久化线程 (m_gtid_persister)

在ddl recover完成后启动,参考函数srv_start_threads_after_ddl_recovery,进行gtid持久化操作

12 全文索引相关线程

  • 全文索引优化线程 (m_fts_optimize) 读取队列fts_optimize_wq消息,对全文索引表进行优化
  • 并行merge线程 fts_parallel_merge_thread,创建索引若存在全文索引时会调用执行
  • 并行tokenization线程 fts_parallel_tokenization_thread 全文的读取或排序时会执行调用

13 IO 线程

  • io_ibuf_thread change buffer thread负责把改变缓冲(change buffer)中的内容刷新到磁盘
  • io_log_thread redo log thread负责把日志缓冲中的内容刷新到redo log文件中
  • io_read_thread read thread为mysql的读线程,默认为4个,其负责将数据页从磁盘上读入,其由innodb_read_io_threads选项控制.用户线程发起读请求并将其放至读请求队列,read threads从读请求队列获取读任务并完成.
  • io_write_thread write thread为mysql的写线程,默认为4个,其负责将数据页从缓冲区写出到磁盘,其由innodb_write_io_threads控制选项控制.page_cleaner线程发起写请求并将其放至写请求队列,write threads从写请求队列获取写任务并完成.

14 并行查询线程

  • 并行查询生成者线程 parallel_read_thread
  • 并行查询消费者线程 parallel_read_ahead_thread
文章来自个人专栏
MySQL源码学习
4 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0