PG數(shù)據(jù)庫服務(wù)器的CPU使用率突然升高該如何分析
?現(xiàn)在基于PG或者脫胎于PG的國產(chǎn)數(shù)據(jù)庫越來越多,再加上PG社區(qū)版用戶也在快速增長,因此多學(xué)點(diǎn)PG的知識對于DBA今后的轉(zhuǎn)型來說,還是挺有用的,因此這幾天我們多討論一些PG相關(guān)的問題。昨天我們討論了PG IO優(yōu)化方面的問題,今天我們就來討論一個(gè)核CPU有關(guān)的問題。今天的議題是,如果PG數(shù)據(jù)庫服務(wù)器的CPU使用率突然升高,我們應(yīng)該從哪幾個(gè)方面去分析。
如果遇到數(shù)據(jù)庫服務(wù)器CPU使用率突然大幅增高或者過高的問題,不論是哪種數(shù)據(jù)庫,我們都要首先查看一下操作系統(tǒng)上有沒有非數(shù)據(jù)庫的進(jìn)程使用了過高的CPU資源,這個(gè)使用TOP工具就可以實(shí)現(xiàn)了,不要因?yàn)镾WAP、大規(guī)模CACHE DROP等操作引發(fā)的CPU使用率突增讓數(shù)據(jù)庫來背鍋了,搞的你分析了一大圈,發(fā)現(xiàn)完全和數(shù)據(jù)庫無關(guān)。幾年前我遇到過一個(gè)案例,一個(gè)用戶讓我?guī)椭治鏊麄兊腃PU怎么突然100%了,我也是沒注意這些問題,直接在數(shù)據(jù)庫里找問題,最后分析了一大圈,發(fā)現(xiàn)負(fù)載啥的都和前一天沒啥區(qū)別,就是CPU使用率多了30%。后來實(shí)在沒招了,用TOP看了一下,發(fā)現(xiàn)了一個(gè)異常的進(jìn)程,居然在做科學(xué)計(jì)算,這個(gè)進(jìn)程正好消耗了30%多的CPU資源。最后客戶那邊確認(rèn)了一下,十分不好意思的說,是一個(gè)幾年前設(shè)置的一個(gè)crontab任務(wù)忘了關(guān)閉了,才導(dǎo)致了今天的問題。幾年前,他們搞數(shù)據(jù)庫合庫,只要CPU使用率在一個(gè)月中沒有一天業(yè)務(wù)高峰期超過35%的數(shù)據(jù)庫,就必須合并到其他數(shù)據(jù)庫中,從而節(jié)約資源。他們干了幾套系統(tǒng)后覺得太辛苦了,部門領(lǐng)導(dǎo)就想了個(gè)招,在月底業(yè)務(wù)高峰期的時(shí)候,讓一個(gè)科學(xué)計(jì)算的任務(wù)跑上幾個(gè)小時(shí),讓符合合并的數(shù)據(jù)庫變少一點(diǎn),大家也少干點(diǎn)活。沒想到這臺服務(wù)器上的任務(wù)忘了關(guān)了,而這些年這套系統(tǒng)的數(shù)據(jù)量越來越大,負(fù)載也越來越高了,沒想到這個(gè)月底業(yè)務(wù)很忙,居然把CPU跑爆掉了。
另外如果在一臺物理機(jī)上跑多個(gè)數(shù)據(jù)庫實(shí)例,我們就不能只看一個(gè)數(shù)據(jù)庫的情況了,而是要看多個(gè)數(shù)據(jù)庫的總體負(fù)載。
除此之外,如果排除了這些問題,單單來討論P(yáng)G數(shù)據(jù)庫,如果真的是PG數(shù)據(jù)庫引發(fā)了CPU突然增加,我們應(yīng)該如何去分析呢?今天我簡單的羅列了一些常用場景,遇到問題的時(shí)候,DBA可以一條條的進(jìn)行排除。
首先,也是可能性最大的方面,出現(xiàn)大查詢或者較高并發(fā)量的SQL執(zhí)行計(jì)劃變壞:如果數(shù)據(jù)庫中的某個(gè)查詢或某組查詢的復(fù)雜度增加,則可能導(dǎo)致CPU使用率的增加;一條常見SQL的執(zhí)行計(jì)劃錯(cuò)誤也會導(dǎo)致執(zhí)行開銷增加,雖然單條SQL的延時(shí)仍然在業(yè)務(wù)能夠忍受的范圍內(nèi),但是總體CPU消耗會大幅增大,如果CPU資源出現(xiàn)瓶頸,那么系統(tǒng)整體性能都會嚴(yán)重下降。
第二,出現(xiàn)嚴(yán)重的資源競爭:如果多個(gè)連接或會話同時(shí)請求大量的數(shù)據(jù),則可能會產(chǎn)生資源競爭,甚至引發(fā)spinlock等自旋鎖爭用,從而導(dǎo)致CPU使用率的增加,分析這方面的原因通過PG的等待事件進(jìn)行分析是比較有效的。
第三,索引缺失導(dǎo)致的SQL執(zhí)行計(jì)劃不夠優(yōu)化:如果數(shù)據(jù)庫表缺少索引,則查詢操作將需要掃描整個(gè)表,從而導(dǎo)致CPU使用率的增加。
第四,磁盤IO瓶頸:如果數(shù)據(jù)庫的磁盤IO不能滿足需求,則可能導(dǎo)致CPU使用率的增加。這一點(diǎn)可能會讓朋友們感到詫異,IO瓶頸的時(shí)候,會話不都在等待IO嗎?怎么會引發(fā)CPU的問題呢?PostgreSQL 使用同步阻塞 IO(Buffered IO),同步阻塞 IO 意味著在完成 IO 操作之前,PostgreSQL 會阻塞等待 IO 操作的完成。當(dāng)數(shù)據(jù)庫服務(wù)器需要讀寫磁盤數(shù)據(jù)時(shí),它會阻塞其他操作,直到 IO 操作完成。在這種情況下,IO延時(shí)會比平時(shí)高很多,CPU使用率中的IOWAIT的比例也會比較高。
第五,數(shù)據(jù)庫維護(hù)任務(wù):如果數(shù)據(jù)庫正在進(jìn)行大型的維護(hù)任務(wù)(例如VACUUM,ANALYZE等),則可能導(dǎo)致CPU使用率的增加。
第六,緩沖污染:這種情況出現(xiàn)幾率較低,而且出現(xiàn)后也很難被發(fā)現(xiàn)。當(dāng)緩存中的數(shù)據(jù)大多數(shù)是很少使用的數(shù)據(jù)時(shí),就會出現(xiàn)緩存污染,導(dǎo)致頻繁的緩存未命中,導(dǎo)致 CPU 利用率增加。當(dāng)緩存污染發(fā)生時(shí),CPU 會花更多的時(shí)間從存儲中讀取數(shù)據(jù),而花更少的時(shí)間從緩存中執(zhí)行指令。 這會導(dǎo)致整體系統(tǒng)性能下降和 CPU 使用率增加。對于PG這種shared_buffers配置占OS比例較低,采用DOUBLE BUFFER機(jī)制的數(shù)據(jù)庫系統(tǒng),出現(xiàn)緩沖污染的幾率遠(yuǎn)大于Oracle等數(shù)據(jù)庫。緩沖污染一旦產(chǎn)生,在SQL執(zhí)行計(jì)劃不發(fā)生變化的情況下,也會產(chǎn)生較為嚴(yán)重的性能下降,因此需要避免。對于經(jīng)常出現(xiàn)類似問題的數(shù)據(jù)庫,可以通過使用各種預(yù)熱插件來不斷預(yù)熱熱數(shù)據(jù),從而防止緩沖污染。
第七,某張經(jīng)常全表掃碼的小表因?yàn)榕蛎浂蝗蛔兇螅哼@種情況出現(xiàn)概率較低,不過也比較容易出現(xiàn),如果某張表關(guān)閉了VACUUM并且常有UPDATE操作,那么經(jīng)過一段時(shí)間積累,可能引發(fā)性能問題。
導(dǎo)致CPU使用率突然增高的可能性還有很多,不過對于PG數(shù)據(jù)庫來說,大部分此類問題都是大并發(fā)SQL或者SQL執(zhí)行計(jì)劃變壞引發(fā),加強(qiáng)SQL問題的監(jiān)控一般來說能解決大多數(shù)PG的CPU問題。今天時(shí)間有限,僅僅討論了一下常見的故障場景。不斷積累這方面的知識庫是企業(yè)和DBA應(yīng)該做的事情,如果能夠通過社區(qū)共同積累此類問題,那就會事半功倍。也希望大家有興趣加入我們的DBAIOPS社區(qū),共同來做這項(xiàng)工作。這項(xiàng)工作的成果會發(fā)布在D-SMART社區(qū)版中,我們也會定期通過文章匯報(bào)匯總的情況。?