美文网首页
MySQL:master线程统计/RW-LOCK统计/page分

MySQL:master线程统计/RW-LOCK统计/page分

作者: 重庆八怪 | 来源:发表于2021-09-07 17:52 被阅读0次

一、问题来源

问1 ,为啥5.7的这个值为0


image.png

问2:为啥8.0的这个值为0

image.png

二、关于RW LOCK

其实Innodb中并发控制结构分为rw lock,mutex(TTASEventMutex)和event(带有条件变量),主要作为Innodb的并发访问控制,这部分非常复杂,还需要学习,我们通常在show engine innodb中看到的mutex或者rw lock就是他们。比如:

  • rw lock其中一个作用就是作为buffer page(BPageLock)的保护,通常用于page的并发访问,比如修改和读取buffer page需要上不同的锁。
  • mutex其中一个作用就是作为buffer block(BPageMutex 类型为TTASEventMutex)的保护,比如需要修改/访问 block io fix部分则需要加这个锁。

rw lock和mutex(TTASEventMutex)都会接受参数的控制:

| innodb_spin_wait_delay             | 6     |
| innodb_sync_spin_loops             | 30    |

逻辑大概如下:

rw_lock_s_lock_spin 函数
如果第一次获取失败
  开启spin获取,则spins+1
    一层循环开启:
      二层循环,循环次数为srv_n_spin_wait_rounds(sync_spin_loops)
        等待每次等待时长srv_spin_wait_delay(大概为空循环的次数默认为6(srv_spin_wait_delay)*50(srv_spin_wait_pause_multiplier) 300次)
        如果获取了lock的使用权则结束二层循环
        否则需要等满srv_n_spin_wait_rounds
      如果等待满srv_n_spin_wait_rounds,则归还
      CPU给操作系统,等待下次CPU的调度
      再次调度的时候,rounds+1
      再次尝试获取锁资源如果获取成功,则退出一层循环
      如果获取锁资源如果获取失败,则OS waits+1,且进入muext等待
      ->sync_array_wait_event(sync_arr, cell); //等待唤醒,唤醒后继续判断,存在多个线程同时竞争的情况
      唤醒后再次循环二层循环,尝试获取锁资源      
    一层继续循环

sync_spin_loops的内部定义为srv_n_spin_wait_rounds
如果我们将经历srv_n_spin_wait_rounds*srv_spin_wait_delay*srv_spin_wait_pause_multiplier:
默认为30*6*50=9000(代码中)
看做一轮等待。那么从逻辑来看定义如下:

  • spins代表是spin获取的次数,如果第一次就获取成功了则这里是为0的
  • rounds代表是经历多少轮数才获取到lock的使用权。当然最后一轮可能提前获取到使用权。
  • OS waits代表是经历了多少轮的等待才获取了lock的使用权。

那么有如下结论

  • spins越少越好,代表第一次获取成功了
  • OS waits大量少于rounds越好,代表偶虽然第一次获取失败,但是第spin一次就获取成功了

但是myql 5.7中spins中关于x lock和s lock 对于这个计数是没有做的,8.0.23有计数。所以5.7这里可能是0。

并且注意这里是RW-LATCH INFO因此mutex是不包含的。

三、关于8.0 master线程的简析

master线程主要是每秒醒来干活,包含:

  • changer buffer 合并
  • flush redo
  • 唤醒purge线程干活
  • checkpoint(8.0剥离成了单独的checkpoint线程)

但是其中包含active和idle的方式,其判断主要是arcive计数器和上次是否相同,不相同则是active方式。那么我看了一下如下情况会进入active方式:

  • 事务提交一次,增加一次active计数。
  • update/delete/insert 总数超过了2的32次方就增加一次active计数。
  • 出现rollback,每行记录都会触发增加一次active计数。
  • innodb关闭表,增加一次active计数。

我们实际上可以从这个信息大概可以看出数据库数据的繁忙程度。但是在8.0中全局变量srv_log_writes_and_flush并没有做任何修改,因此初始化为0它一值都是0。5.6 5.7是有修改的,但是值没有什么意义就是 srv_active+ srv_idle,代表master线程触发的写盘操作。

四、page分配内存

(buf_page_get_gen->buf_buddy_alloc_low)

  1. 首先从freelist中获取块,不能获取则转下一个逻辑
  2. 从LRU中获取,受到参数innodb_lru_scan_depth的影响表示每次检查的块的数量,其中有一些条件不能获取
    • 块本生是脏块
    • 块本生被io fix了
      如果获取成功将从hash table中去掉,并且从lru放到free list中如果循环完整个LRU链表都不能获取则转下一个逻辑
  3. 如果扫描了整个LRU都不能获取,那么说明块可能脏块比较多了进行单块刷盘,这个时候是直接fsync了(buf_flush_single_page_from_LRU)

其他:

8.0.23
    mutex_enter(&buf_pool->flush_state_mutex); //为TTASEventMutex

      os_event_reset(buf_pool->no_flush[flush_type]); //为os_event  不受spin参数影响,例子https://www.jianshu.com/p/24b212286a1b

那么研究方向应该是TTASEventMutex\rw lock\os_event 各自的实现

相关文章

网友评论

      本文标题:MySQL:master线程统计/RW-LOCK统计/page分

      本文链接:https://www.haomeiwen.com/subject/qnlpwltx.html