加入收藏 | 设为首页 | 会员中心 | 我要投稿 大连站长网 (https://www.0411zz.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

主机cpu 之-sys使用率过高

发布时间:2022-03-22 13:36:18 所属栏目:MySql教程 来源:互联网
导读:学习大神的http://mp.weixin.qq.com/s/hXtCzSnlVfo9Cq92538ipw自己整理一点思路 1.0top看cpu消耗,发现sys比usr要高不少,这非常不正常 1.1使用pstack看 MySQL所有线程的调用栈: InnoDB线程同步机制 我们知道linux线程同步有Mutex,spin lock,条件变量,rw lo
       学习大神的http://mp.weixin.qq.com/s/hXtCzSnlVfo9Cq92538ipw自己整理一点思路
1.0top看cpu消耗,发现sys比usr要高不少,这非常不正常
 
     1.1使用pstack看 MySQL所有线程的调用栈:
 
     InnoDB线程同步机制
     我们知道linux线程同步有Mutex,spin lock,条件变量,rw lock等多种同步机制,InnoDB并没有直接使用系统的同步机制,而是自己定义了互斥结构数据结构kernel_mutex,将系统的spin lock,mutex,和条件变量融合一起
 
     kernel_mutexmutex对象的中重要的结构成员为os_event和lock_word。
 
     kernel_mutex主要涉及mutex_create,mutex_enter,mutex_exit函数,会分别使用glibc的malloc()和free()调用动态分配和释放内存
     封装mutex和条件变量,图中绿色框区域
MySQL线程之间发送异步信号来进行同步主要通过os_event_struct结构体中的os_mutex(封装os的pthread_mutex_t)和cond_var(封装os的pthread_cond_t)成员对象实现。当InnoDB在获取锁的时候,首先先努力自旋一段时间,如果超过innodb_sync_spin_loops的阈值,就会通过函数os_event_wait_low()在os_event_struct->cond_var上等待。如图,当某个线程释放了锁的时候,通过os_cond_broadcast尝试发送广播唤醒所有等待os_event_struct->cond_var条件变量的线程.这些线程被唤醒后又继续竞争争抢os_event_struct->os_mutex
spin lock,图中黄色框区域
通过lock_word做spin wait。线程想要争抢锁的时候先判断这个值,如果lock_word为1就继续自旋等待。如果发现其他线程释放了锁该值变为0的时候,就通过test_and_set改为1,"告诉"其他线程这把锁被持有了
InnoDB这样设计的目的都是延缓线程被挂起并进入os wait的速度,因为每一次进入os wait等待被唤醒或者唤醒都会进行一次上下文切换.但是也只能是延缓,并不能阻止,如果持续恶化得不到环境,最后仍然会进入os的等待队列,将会产生大量的上下文切换。但是有两个问题:
 
kernel_mutex是个全局锁,保护事务,buffer pool,锁,等InnoDB存储引擎实现的大部分对象.当MySQL突然有大量访问,并发一旦非常高的时候,mutex冲突非常剧烈,此时临界区变得非常大,同时也会浪费cpu很多时间空转。所以这也解释了sys cpu大量消耗在自选空转中
并且并发高的时候会频繁调用malloc()申请内存,而glibc本身的malloc()本书频繁调用系统mutex_lock()和unlock(),在多线程高并发场景下并且资源不足的场景下,也会造成系统各种mutex竞争严重。大量线程被挂起等待os pthread_cond_broadcast广播被唤醒,随之而来的是大量的上下文切换
通过dstat看到此时cpu每秒有近20W次的上下文切换,综上所述,sys cpu负载高主要以下:
 
(1)cpu内核态spin,大量线程cpu在内核态自旋等待
(2)系统上下文切换,又分为:
spin仍然失败的,最终进入os wait,调用pthread_cond_wait等待条件满足时被唤醒
malloc()频繁加减os mutex,且系统内存紧张
 
1.3继续观察内存分配使用的情况.
sar -B 看内存页回收,其中pgscank/s,对应kswapd回收,pgscand/s对应的MySQL线程直接回收
 
pgscand/s不为0,说明内存资源紧张,MySQL直接回收内存。
 
可是free命令看内存free并没有用光。经过一番调查发现是numa搞的鬼
用numactl --hardware命令看:
 
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3node 0 size: 32733 MB
node 0 free: 1900 MB
node 1 cpus: 4 5 6 7node 1 size: 32768 MB
node 1 free: 20 MB
node distances:
node   0   1  0:  10  20  1:  20  10
虽然内存整体free没有用光,但是在numa默认的内存分配机制下,内存使用严重不均,node0还十分充足,但是node1几乎用光
 
还可以使用strace来诊断!

(编辑:大连站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!