今天,有個哥們碰到一個問題,他有一個從庫,只要是啟動MySQL,CPU使用率就非常高,其中sys占比也比較高,具體可見下圖。
注意:他的生產環境是物理機,單個CPU,4個Core。
於是,他抓取了CPU的歷史信息,發現CPU飙高大概是從2017年1月1日8點10分開始的。
但是這個從庫的負載並不高,通過他反饋的“show processlist”和“show engine innodb status\G”的結果可以看出來
show processlist
mysql> show processlist; +-----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +-----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+ | 1 | system user | | NULL | Connect | 57892 | Waiting for master to send event | NULL | | 2 | system user | | NULL | Connect | 23 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL | | 108 | root | localhost | NULL | Query | 0 | NULL | show processlist | +-----+-------------+-----------+------+---------+-------+-----------------------------------------------------------------------------+------------------+ 3 rows in set (0.00 sec)
show engine innodb status
在這裡,只截取了“row operations”這一部分
... -------------- ROW OPERATIONS -------------- 0 queries inside InnoDB, 0 queries in queue 1 read views open inside InnoDB Main thread process no. 3034, id 140218088003328, state: waiting for server activity Number of rows inserted 7500, updated 237481, deleted 884, read 31371340 0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s ---------------------------- ...
再次回到CPU sys態較高的事實上,一般sys較高就意味著系統在頻繁調用內核代碼。如果是這樣的話,通過perf top就能定位系統什麼操作執行得比較多。
結果卻顯示,無任何異常操作,尤其是內核部分的,排在第一位的還是MySQL的後台進程。
一切看來是如此的詭異,MySQL本身幾乎沒有負載,但是CPU sys使用率較高,而且,只要關閉MySQL,CPU負載又會降下來。
最後,還是從/var/log/messages中找到些許蛛絲馬跡。
聯想到前幾天的閏秒新聞,懷疑這個是閏秒造成的。
事實上,2012年發生的閏秒調整事件(2012年6月30日23:59:59)在全球造成了較大的影響,很多網站的服務器的CPU使用率飙升,導致網站被拖垮。
後來確認為Linux內核版本存在缺陷,在進行閏秒調整時可能會引起系統時鐘服務ntpd進程死鎖,並造成Linux系統重啟。包括SUSE、RedHat等所有Linux kernel版本在2.6.29以下且開通了NTP服務的Linux系統都存在本次風險。如同步的時鐘源對象為內部時鐘源,理論上不會有此影響;如同步的時鐘源對象為官方時鐘源,則會存在上述風險。
該缺陷在2012年修復後,在2015年同樣的閏秒調整事件中就沒有造成極大的影響。
之前發生的閏秒調整導致MySQL服務器CPU sys飙高的問題,
具體可參考:
https://blog.mozilla.org/it/2012/06/30/mysql-and-the-leap-second-high-cpu-and-the-fix/
解決方法:
1. 重啟服務器
2. 重新設置時間
/etc/init.d/ntpd stop; date -s now
很明顯,第2種方法更實用。
重新設置時間後,CPU sys負載馬上下降了。
那麼,如何避免此類問題的發生呢?
簡單方法:
在發生閏秒前停掉ntpd服務,發生後再開啟ntpd
其它較優雅的方法,可參考:
https://www.percona.com/blog/2016/12/27/prepare-for-the-new-leap-second/
https://developers.redhat.com/blog/2015/06/01/five-different-ways-handle-leap-seconds-ntp/
PS:閏秒不是23:59:60秒麼?為什麼該問題發生的時間是8點。
因為23:59:60是格林威治時間,我們是東八區,所有要增加8個小時。