PostgreSQL流複製案例分析 | Startup 進程waiting問題分析

  • 2019 年 11 月 21 日
  • 筆記

一、 作者介紹

劉雪柏,目前就職於諾基亞東軟通信有限公司,高級軟件工程師,從事數據庫相關工作,聯繫方式: [email protected]

二、 問題現象

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