ITPub博客

首页 > > > PostgreSQL流复制案例分析 | Startup 进程waiting问题分析

PostgreSQL流复制案例分析 | Startup 进程waiting问题分析

作者:wangliyun 时间:2020-03-12 17:09:18 0 删除 编辑

一、 作者介绍

刘雪柏,目前就职于诺基亚东软通信有限公司,高级软件工程师,从事数据库相关工作,联系方式: aiden.liu@qq.com。

 

二、 问题现象

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=<optimized out>) 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=<optimized out>) at standby.c:315

#5  ResolveRecoveryConflictWithSnapshot (latestRemovedXid=<optimized out>, 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代码中有如下注释:

 

startup 进程在执行清除tuples前需要确认没有活动的查询,并且这些tuples对于活动查询仍然可见。

跟着ResolveRecoveryConflictWithSnapshot->ResolveRecoveryConflictWithVirtualXIDs->WaitExceedsMaxStandbyDelay->GetStandbyLimitTime

standby.c代码中GetStandbyLimitTime函数:

 

从代码中可以看出startup 进程在执行清除tuples前需要确认没有活动的查询有等待时间限制,fromStream的情况超过

max_standby_streaming_delay参数时间限制会kill掉正在执行的查询,其他情况如果超过了max_standby_archive_delay

参数时间限制会调用CancelVirtualTransaction函数 kill掉正在执行的查询。

standby.c相关代码

 

procarray.c相关代码

 

四、 小结

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秒。



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69917105/viewspace-3124323/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-04-19

  • 博文量
    213
  • 访问量
    317