PG數(shù)據(jù)庫(kù)遇到內(nèi)存問(wèn)題要立即進(jìn)行分析的場(chǎng)景并不多,因?yàn)榇蠖鄶?shù)PG數(shù)據(jù)庫(kù)的內(nèi)存使用率過(guò)高的報(bào)警并不意味著內(nèi)存使用情況異常,內(nèi)存真的不夠用了。因?yàn)镻G數(shù)據(jù)庫(kù)是使用DOUBLE BUFFERING機(jī)制的,大量的內(nèi)存很可能被BUFFER/CACHE占用了。
?前幾天寫(xiě)了CPU分析與IO分析的文章,本來(lái)昨天想再湊一個(gè)內(nèi)存分析的,不過(guò)因?yàn)樽蛱煲淮笤缇腿グ菰L客戶(hù)了,所以今天補(bǔ)上。今天早上本來(lái)和優(yōu)諾的傲寒約好了去他那里取取經(jīng),聽(tīng)聽(tīng)他對(duì)智能化運(yùn)維的看法,不過(guò)因?yàn)橐恍┢渌才排R時(shí)取消了,十分遺憾。
PG數(shù)據(jù)庫(kù)遇到內(nèi)存問(wèn)題要立即進(jìn)行分析的場(chǎng)景并不多,因?yàn)榇蠖鄶?shù)PG數(shù)據(jù)庫(kù)的內(nèi)存使用率過(guò)高的報(bào)警并不意味著內(nèi)存使用情況異常,內(nèi)存真的不夠用了。因?yàn)镻G數(shù)據(jù)庫(kù)是使用DOUBLE BUFFERING機(jī)制的,大量的內(nèi)存很可能被BUFFER/CACHE占用了。
上面的free命令可以看到32G內(nèi)存使用了15G多,但是free只剩下599M了,BUFF/CACHE占了15G多。不過(guò)如果我們看available,有9G多,當(dāng)前這個(gè)PG服務(wù)器的內(nèi)存是充足的。從這個(gè)例子上看到,我們看fee命令的結(jié)果的時(shí)候,不應(yīng)該看free,看available更為準(zhǔn)確。
/proc/meminfo可以更詳細(xì)的看到OS的內(nèi)存情況,我們可以關(guān)注紅框里的幾個(gè)數(shù)字。Dirty是FILE CACHE中尚未寫(xiě)入磁盤(pán)的臟數(shù)據(jù),是無(wú)法快速丟棄的內(nèi)存,如果這個(gè)指標(biāo)持續(xù)較高,那么說(shuō)明OS的回寫(xiě)機(jī)制或者磁盤(pán)存在性能問(wèn)題,是需要關(guān)注的。PageTalbes如果比較大,對(duì)于PG數(shù)據(jù)庫(kù)來(lái)說(shuō),很可能是配置了較大的shared_buffers,但是沒(méi)有啟用HugePages,這樣除了會(huì)影響PG數(shù)據(jù)庫(kù)訪問(wèn)內(nèi)存的性能外,還會(huì)占據(jù)大量的不必要的內(nèi)存。AnonHugePages指標(biāo)大于零說(shuō)明沒(méi)有關(guān)閉透明大頁(yè),而且已經(jīng)使用了透明大頁(yè),對(duì)于PG、Oracle等數(shù)據(jù)庫(kù)來(lái)說(shuō),透明大頁(yè)的缺點(diǎn)大于優(yōu)點(diǎn),會(huì)引起內(nèi)存碎片,建議關(guān)閉。另外需要關(guān)注的是SWAP的使用率,如果FREE內(nèi)存很大,但是SWAP使用率超過(guò)20%,很可能是OS的NUMA內(nèi)存方面的配置存在問(wèn)題,沒(méi)有全局分配內(nèi)存。
遇到PG數(shù)據(jù)庫(kù)的空閑內(nèi)存不足的問(wèn)題,首先通過(guò)這些機(jī)制分析OS內(nèi)存是否真的存在風(fēng)險(xiǎn),如果沒(méi)有發(fā)現(xiàn)明顯的風(fēng)險(xiǎn),暫時(shí)就不需要做進(jìn)一步的分析了。如果真的存在風(fēng)險(xiǎn),我們還可以繼續(xù)在OS層面查找。
ps aux –sort -rss |head -20命令可以查出rss使用最高的20個(gè)進(jìn)程。然后找出存在問(wèn)題的進(jìn)程,用smem做進(jìn)一步分析。
如果找到了存在問(wèn)題的進(jìn)程,可以用smem進(jìn)一步去做分析。其中USS是進(jìn)程私有內(nèi)存,PSS是私有內(nèi)存+共享內(nèi)存的總和。
如果在OS層面找到了存在問(wèn)題的進(jìn)程,那么可以使用上面的語(yǔ)句去查找其PG會(huì)話的信息,進(jìn)一步進(jìn)行定位。一般情況下,PG會(huì)話占用較多的內(nèi)存可能是做VACUUM、ANALYZE、排序,表連接、內(nèi)存臨時(shí)表等操作。
如果不存在某個(gè)進(jìn)程使用內(nèi)存過(guò)多,而是大量的進(jìn)程都占用差不多的內(nèi)存,那么很可能是數(shù)據(jù)庫(kù)并發(fā)執(zhí)行某類(lèi)SQL,使用了排序,表連接等臨時(shí)內(nèi)存分配。這時(shí)候就要去分析數(shù)據(jù)庫(kù)的性能是否存在問(wèn)題,導(dǎo)致了某類(lèi)SQL或者某條SQL并發(fā)執(zhí)行量較大。亦或是某條SQL的執(zhí)行計(jì)劃出現(xiàn)了錯(cuò)誤,導(dǎo)致執(zhí)行時(shí)間過(guò)長(zhǎng),并發(fā)執(zhí)行量過(guò)大,占用了大量物理內(nèi)存。