移动云海山数据库(He3DB)-InnoDB后台线程(MasterThread)

61 阅读3分钟

Master Thread是非常核心的后台线程,具有最高的线程优先级,主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性,包括:脏页的刷新;合并插入缓冲;undo页的回收等。 srv0srv.cc-->srv_master_thread image.png

一、主循环loop

image.png

1、srv_master_sleep 睡眠1秒 image.png 2、srv_master_do_active_tasks 服务器非空闲时的操作 image.png 2.1 log_free_check 确保重做日志文件中有足够的可重用空间:如果不够,就刷新日志缓冲区或创建新的检查点 image.png 2.2 ibuf_merge_in_background 合并 5%*srv_io_capacity 大小的 insert buffer, srv_io_capacity表示磁盘IO的吞吐量,默认值是200,可以根据磁盘的性能做调整 image.png 2.2.1调用ibuf_merge_in_background(bool full) 默认为5%,如果缓冲池使用超过一半,则加上超过一半的部分所占的比例 image.png 2.3刷新一次重做日志缓冲至磁盘 image.png 2.3.1如果current_time - srv_last_log_flush_time)>= srv_flush_log_at_timeout则调用log_buffer_sync_in_background刷新日志至磁盘。 由于每次循环默认睡1s,srv_flush_log_at_timeout=1,所以该次日志刷新为必做操作 image.png 2.4每间隔47秒执行一次 LRU 缓存清理检查,通过逐出未使用的表,在LRU缓存中腾出空间,最大扫描表长为百分之50 image.png 2.4.1 srv_master_evict_from_table_cache 逐出未使用的表 image.png ……|-->需要持有dict_operation_lock的x锁,以及dict_sys->mutex image.png ……|--> dict_make_room_in_cache image.png …………|-->如果dict_sys->table_LRU(可以从缓存中收回的表的链表)的长度小于table_def_size,不检查直接返回 image.png …………|-->否则从LRU尾部开始对于可以驱逐的表从dict cache中驱逐,直到table_LRU为空,或者检查长度>50%,或者dict cache长度<=table_def_size停止扫描 image.png ………………|-->dict_table_can_be_evicted table可以被驱逐的情况: image.png image.png

(1)该表当前没有被任何事务引用 image.png (2)该表没有加锁 image.png (3)该表的索引没有被adaptive hash index引用 image.png ………………|-->dict_table_remove_from_cache_low 从dict cache移除表 image.png 2.5每间隔7秒执行一次设置新的 checkpoint,只向 log file 中写入 LSN,不做脏页刷新 image.png 3、 srv_master_do_idle_tasks 服务器空闲时的操作 image.png 3.1确保重做日志文件中有足够的可重用空间:如果不够,就刷新日志缓冲区或创建新的检查点 image.png 3.2(区别于非空闲时)合并 100%*srv_io_capacity 大小的 insert buffer image.png 3.2.1调用ibuf_merge_in_background(bool full) image.png 3.3(区别于非空闲时)执行LRU缓存清理,扫描100% image.png 3.4刷新一次重做日志缓冲至磁盘 image.png 3.5设置新的checkpoint,只向log file中写入LSN,不做脏页刷新 image.png

二、暂停线程

image.png 1、当srv_force_recovery >= 2时进入暂停线程。 image.png srv_force_recovery默认为0,非0时会跳过崩恢复流程中的表空间校验过程,且非0时,不允许用户对数据进行任何修改。 image.png 1.1 srv_force_recovery可选值与影响,大的数字包含前面所有数字的影响。 -如果你能以3或更低值恢复/转储你的表时,这种情况库还相对安全的,因为只在相对独立的页上的一些数据会丢失。 -大于等于4时,数据库损坏度比较大危险,因为数据文性被永久地损坏。 -值6被认为是严重的,数据库页被留在一个陈旧的状态,这反过来又可能带给B-trees和其它数据库结构更多的损坏。 -作为一个安全措施,InnoDB 在该值大于0时阻止INSERT,UPDATE或DELETE操作。设为4或更高时,InnoDB库处于只读模式。 image.png 1:即使检查到损坏的页也让服务器继续运行 2:阻止主线程的运行,如主线程在清除过程中发生崩溃则会阻止 3:在recovery后不执行事务回滚操作 4:不执行插入缓冲的合并操作 5:启动数据库时不查看undo日志,InnoDB存储引擎会将未提交的事务视为已提交 6:recovery时不执行日志前滚操作