Postgresql startup 进程waiting问题原因分析

一、问题现象:
Postgresql 11.2版本物理复制,startup 进程命令行有时会出现waiting 标识。本文分析了出现waiting 标识的原因。

二、问题分析:
通过ps -ef | grep startup 监控startup 进程。
postgres: startup process recovering 0000000100000000000000A6
当startup 进程出现waiting的标识。通过pstack查看startup 进程调用堆栈
[postgres@sscloud21 ~]$ pstack 197120
#0 0x00007f695b6faf53 in __select_nocancel () from /lib64/libc.so.6
#1 0x000000000088c97a in pg_usleep (microsec=) at pgsleep.c:56
#2 0x0000000000729ef9 in WaitExceedsMaxStandbyDelay () at standby.c:201
#3 ResolveRecoveryConflictWithVirtualXIDs (waitlist=0x1c706e0, reason=reason@entry=PROCSIG_RECOVERY_CONFLICT_SNAPSHOT) at standby.c:262
#4 0x000000000072a10e in ResolveRecoveryConflictWithVirtualXIDs (reason=PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, waitlist=) at standby.c:315
#5 ResolveRecoveryConflictWithSnapshot (latestRemovedXid=, node=…) at standby.c:313
#6 0x00000000004c23be in heap_xlog_clean (record=0x1c00698) at heapam.c:8198
#7 heap2_redo (record=0x1c00698) at heapam.c:9351
#8 0x0000000000503e85 in StartupXLOG () at xlog.c:7306
#9 0x00000000006d82b1 in StartupProcessMain () at startup.c:211
#10 0x0000000000512275 in AuxiliaryProcessMain (argc=argc@entry=2, argv=argv@entry=0x7fff8b5d99b0) at bootstrap.c:441
#11 0x00000000006d53a0 in StartChildProcess (type=StartupProcess) at postmaster.c:5331
#12 0x00000000006d7b75 in PostmasterMain (argc=argc@entry=3, argv=argv@entry=0x1bd0e40) at postmaster.c:1371
#13 0x000000000048124f in main (argc=3, argv=0x1bd0e40) at main.c:228
检查源码发现,startup 进程正在执行 XLOG_HEAP2_CLEAN 类型的redo操作(vacuum命令产生的块清除redo)。
heapam.c代码中有如下注释:
Postgresql startup 进程waiting问题原因分析_第1张图片
startup 进程在执行清除tuples前需要确认没有活动的查询,并且这些tuples对于活动查询仍然可见。
跟着ResolveRecoveryConflictWithSnapshot->ResolveRecoveryConflictWithVirtualXIDs->WaitExceedsMaxStandbyDelay->GetStandbyLimitTime
standby.c代码中GetStandbyLimitTime函数:
Postgresql startup 进程waiting问题原因分析_第2张图片
从代码中可以看出startup 进程在执行清除tuples前需要确认没有活动的查询有等待时间限制,fromStream的情况超过
max_standby_streaming_delay参数时间限制会kill掉正在执行的查询,其他情况如果超过了max_standby_archive_delay
参数时间限制会调用CancelVirtualTransaction函数 kill掉正在执行的查询。
standby.c相关代码
Postgresql startup 进程waiting问题原因分析_第3张图片
procarray.c相关代码
Postgresql startup 进程waiting问题原因分析_第4张图片
三、小结
1、原因: 重放XLOG_HEAP2_CLEAN 类型的redo操作不允许有查询,如果有会等待,等待时间由max_standby_streaming_delay/max_standby_archive_delay控制。
2、解决这个问题可以控制slave端禁止执行查询操作,或者调整max_standby_streaming_delay/max_standby_archive_delay参数的值到可接受的范围。
3、max_standby_streaming_delay/max_standby_archive_delay参数默认值30秒。

你可能感兴趣的:(postgresql)