-
Notifications
You must be signed in to change notification settings - Fork 55
SEMAPHORES
xiaoboluo768 edited this page Jun 13, 2020
·
4 revisions
- 第三段信息部分
- 如果有高并发的工作负载,你就要关注下接下来的段(SEMAPHORES信号量),它包含了两种数据:事件计数器以及可选的当前等待线程的列表,如果有性能上的瓶颈,可以使用这些信息来找出瓶颈,不幸的是,想知道怎么使用这些信息还是有一点复杂,下面先给出一些解释:
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 68581015, signal count 218437328
--Thread 140653057947392 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff536c7d3c0 created in file buf0buf.c line 916
a writer (thread id 140653057947392) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
--Thread 140653677291264 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff53945b240 created in file buf0buf.c line 916
a writer (thread id 140653677291264) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
Mutex spin waits 1157217380, rounds 1783981614, OS waits 10610359
RW-shared spins 103830012, rounds 1982690277, OS waits 52051891
RW-excl spins 43730722, rounds 602114981, OS waits 3495769
Spin rounds per wait: 1.54 mutex, 19.10 RW-shared, 13.77 RW-excl
# 内容比较多,下面分段依次解释:
OS WAIT ARRAY INFO: reservation count 68581015, signal count 218437328 #这行给出了关于操作系统等待数组的信息,\
它是一个插槽数组,innodb在数组里为信号量保留了一些插槽,操作系统用这些信号量给线程发送信号,使线程可以继续运行,\
以完成它们等着做的事情,这一行还显示出innodb使用了多少次操作系统的等待:保留统计(reservation count)显示了\
innodb分配插槽的频度,而信号计数(signal count)衡量的是线程通过数组得到信号的频度,操作系统的等待相对于\
空转等待(spin wait)要昂贵些。
--Thread 140653057947392 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff536c7d3c0 created in file buf0buf.c line 916
a writer (thread id 140653057947392) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
--Thread 140653677291264 has waited at btr0pcur.c line 437 for 0.00 seconds the semaphore:
S-lock on RW-latch at 0x7ff53945b240 created in file buf0buf.c line 916
a writer (thread id 140653677291264) has reserved it in mode exclusive
number of readers 0, waiters flag 1, lock_word: 0
Last time read locked in file row0sel.c line 3097
Last time write locked in file /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151
# 这部分显示的是当前正在等待互斥量的innodb线程,在这里可以看到有两个线程正在等待,每一个都是以--Thread <数字> has waited...开始,\
这一段内容在正常情况下应该是空的(即查看的时候没有这部分内容),除非服务器运行着高并发的工作负载,促使innodb采取让操作系统等待的措施,\
除非你对innodb源码熟悉,否则这里看到的最有用的信息就是发生线程等待的代码文件名 /usr/local/src/soft/mysql-5.5.24/storage/innobase/buf/buf0buf.c line 3151。
# 在innodb内部哪里才是热点?举例来说,如果看到许多线程都在一个名为buf0buf.c的文件上等待,那就意味着你的系统里存在着缓冲池竞争,\
这个输出信息还显示了这些线程等待了多少时间,其中waiters flag显示了有多少个等待着正在等待同一个互斥量。 如果waiters flag为0\
那就表示没有线程在等待同一个互斥量(此时在waiters flag 0后面可能可以看到wait is ending,表示这个互斥量已经被释放了,\
但操作系统还没有把线程调度过来运行)。
# 你可能想知道innodb真正等待的是什么,innodb使用了互斥量和信号量来保护代码的临界区,如:限定每次只能有一个线程进入临界区,\
或者是当有活动的读时,就限制写入等。在innodb代码里有很多临界区,在合适的条件下,它们都可能出现在那里,常常能见到的一种情形是:\
获取缓冲池分页的访问权的时候。
# 在等待线程之后的部分信息如下,这部分显示了更多的事件计数器,在每一个情形中,都能看到innodb依靠操作系统等待的频度:
Mutex spin waits 1157217380, rounds 1783981614, OS waits 10610359 #这行显示的是跟互斥量相关的几个计数器
RW-shared spins 103830012, rounds 1982690277, OS waits 52051891 #这行显示读写的共享锁的计数器
RW-excl spins 43730722, rounds 602114981, OS waits 3495769 #这行显示读写的排他锁的计数器
Spin rounds per wait: 1.54 mutex, 19.10 RW-shared, 13.77 RW-excl
# innodb有着一个多阶段等待的策略,首先,它会试着对锁进行空转等待,如果经历了一个预设的空转等待周期\
(设置innodb_sync_spin_loops配置变量命令)之后还没有成功,那就会退到更昂贵更复杂的等待数组中。空转等待的成本相对较低,\
但是它们要不停地检查一个资源能否被锁定,这种方式会消耗CPU周期,但是,这没有听起来那么糟糕,因为当处理器在等待IO时,\
一般都有一些空闲的CPU周期可用,即使是没有空闲的CPU周期,空等也要比其他方式更加廉价一些。然而,当另外一个线程能做一些事情的时候,\
空转等待也还会把CPU独占着。空转等待的替代方案就是让操作系统做上下文切换,这样,当一个线程在等待时,另外一个线程就可以被运行,\
然后,通过等待数组里的信号量发出信号,唤醒那个沉睡的线程,通过信号量来发送信号是比较有效的,但是上下文切换就很昂贵,\
这很快就会积少成多,每秒钟几千次的切换会引发大量的系统开销。
# 你可以通过修改innodb_sync_spin_loops的值,试着在空转等待与操作系统等待之间达成平衡,不要担心空转等待,除非你在一秒里看到\
几十万个空转等待。此时,你可以考虑performance_schema库或者show engine innodb mutex;查看下相关信息。
- PS:如果出现大量等待信号量的线程,需要引起足够重视,可能是由于磁盘I/O性能不足或InnoDB引起内部资源争用问题的导致(争用可能是由于并发查询量过大或操作系统线程调度问题)。通过增大系统配置变量innodb_thread_concurrency的值可能会有所帮助,如果需要查询互斥量信息,可以通过SHOW ENGINE INNODB MUTEX语句查看。
上一篇:BACKGROUND THREAD | 下一篇:LATEST FOREIGN KEY ERROR
-
本 WIKI 包含了《千金良方--MySQL 性能优化金字塔法则》一书的代码段加粗命令行命令和SQL语句文本、以及4个附录内容,其中:
- 代码段和高清图单独整理为一个系列文档,如下:
- 每个附录都各自整理成了一个小系列文档,如下:
-
《千金良方--MySQL 性能优化金字塔法则》 一书的作者信息如下:
- 李春、罗小波、董红禹
-
联系人QQ:309969177
-
提示:
-
郑重声明:本WIKI仓库中的资料为电子工业出版社与本书的三位作者共同授权开源,为了在方便大家的同时,避免不必要的纠葛,任何商业与非商业的引用、转载,麻烦大家注明出处,谢谢配合!