1、场景描述
生产机器pg_update升级进程完成后,调用postgres多进程进行SQL压测,发现性能大幅下降,SYS CPU占用很高
2、问题分析
1)机器共2个NODE节点,postgres基本都是跑在NODE1上,跑到后期,出现严重内存占用不均匀,NODE1上内存基本耗尽,NODE0还有不少内存。查看NUMA分配策略:
策略为默认策略,preferred node为当前节点(即本地节点),该策略下内存分配行为遵从:优先分配本地node内存,如果不足才会考虑分配另外节点,和此处NODE0还有大量内存不符。排除NUMA策略因素
2)sys 占用cpu过高
perf热点分析:
可以看出发生了大量的migrate_pages,函数调用关系:__alloc_pages_nodemask -> __alloc_pages_slowpath -> __alloc_pages_direct_compact -> try_to_compact_pages -> compact_zone_order -> compact_zone ->migrate_pages , 页面迁移频繁会导致sys的CPU占用率提高。页面迁移一个是由于内存确实不足,另外是由于内存碎片过多,满足不了连续大内存分配,本场景排除内存不足,所以初步判断是内存碎片过多。
3)查看budyinfo和extfrag查看ZONE的碎片化程度
cat /proc/buddyinfo
Node 0, zone DMA32 225 240 368 422 251 97 26 11 7 4 105
Node 0, zone Normal 2721 3506 4141 2391 1467 761 286 64 10 0 0
Node 1, zone Normal 3369 7124 3901 2187 725 153 12 0 0 0 0
cat /sys/kernel/debug/extfrag/extfrag_index 【extfrag_index越接近1,碎片率越高】
Node 0, zone DMA -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
Node 0, zone DMA32 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000
Node 0, zone Normal -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.985 0.993
Node 1, zone Normal -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 -1.000 0.970 0.985 0.993 0.997
可以看出,两个NODE节点连续大内存非常少,为了满足这种较大内存的分配,不得不频繁的在两个节点上做回收迁移操作。
4)调整watermark提前进行内存回收操作
由于本场景,NODE1内存即将耗尽时发生内存回收,会导致回收和分配不断的反复进行,震荡进行,表现为CPU突发性占用率变高,性能急剧下降。为了使回收变得更平缓,不那么急中进行,可调高watermark进行,
[[email protected] czh]# cat /proc/sys/vm/min_free_kbytes
90112
增加watermark:
echo 2048000 > /proc/sys/vm/min_free_kbytes
调整后再测试:
可以看出CPU中sys利用率大幅下降。系统性能恢复正常。