From 7cc51ec255d1406b0aded6d38d736a4c089afbe6 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Thu, 27 Sep 2018 19:31:18 +0530 Subject: [PATCH] Fix assertion failure when updating full_page_writes for checkpointer. When the checkpointer receives a SIGHUP signal to update its configuration, it may need to update the shared memory for full_page_writes and need to write a WAL record for it. Now, it is quite possible that the XLOG machinery has not been initialized by that time and it will lead to assertion failure while doing that. Fix is to allow the initialization of the XLOG machinery outside critical section. This bug has been introduced by the commit 3b682df326 which added the critical section in function UpdateFullPageWrites, so back-patch through all the supported branches. Reported-by: Dilip Kumar Author: Dilip Kumar Reviewed-by: Michael Paquier and Amit Kapila Backpatch-through: 9.3 Discussion: https://postgr.es/m/CAFiTN-u4BA8KXcQUWDPNgaKAjDXC=C2whnzBM8TAcv=stckYUw@mail.gmail.com --- src/backend/access/transam/xlog.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 5abaeb0..88f81cd 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -9701,6 +9701,7 @@ void UpdateFullPageWrites(void) { XLogCtlInsert *Insert = &XLogCtl->Insert; + bool recoveryInProgress; /* * Do nothing if full_page_writes has not been changed. @@ -9712,6 +9713,13 @@ UpdateFullPageWrites(void) if (fullPageWrites == Insert->fullPageWrites) return; + /* + * Perform this outside critical section so that the WAL insert + * initialization done by RecoveryInProgress() doesn't trigger an + * assertion failure. + */ + recoveryInProgress = RecoveryInProgress(); + START_CRIT_SECTION(); /* @@ -9732,7 +9740,7 @@ UpdateFullPageWrites(void) * Write an XLOG_FPW_CHANGE record. This allows us to keep track of * full_page_writes during archive recovery, if required. */ - if (XLogStandbyInfoActive() && !RecoveryInProgress()) + if (XLogStandbyInfoActive() && !recoveryInProgress) { XLogBeginInsert(); XLogRegisterData((char *) (&fullPageWrites), sizeof(bool)); -- 1.8.3.1