Fix assertion failure when updating full_page_writes for checkpointer.
authorAmit Kapila <akapila@postgresql.org>
Fri, 28 Sep 2018 11:24:40 +0000 (16:54 +0530)
committerAmit Kapila <akapila@postgresql.org>
Fri, 28 Sep 2018 11:24:40 +0000 (16:54 +0530)
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 2c03216d83 which added the XLOG
machinery initialization in RecoveryInProgress code path.

Reported-by: Dilip Kumar
Author: Dilip Kumar
Reviewed-by: Michael Paquier and Amit Kapila
Backpatch-through: 9.5
Discussion: https://postgr.es/m/CAFiTN-u4BA8KXcQUWDPNgaKAjDXC=C2whnzBM8TAcv=stckYUw@mail.gmail.com

src/backend/access/transam/xlog.c

index 3fccb856adbb3feb49d5b2d72db7ffc29501477f..92a3b7954a975115a2731921cd09984aa30fce09 100644 (file)
@@ -9219,6 +9219,7 @@ void
 UpdateFullPageWrites(void)
 {
    XLogCtlInsert *Insert = &XLogCtl->Insert;
+   bool        recoveryInProgress;
 
    /*
     * Do nothing if full_page_writes has not been changed.
@@ -9230,6 +9231,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();
 
    /*
@@ -9250,7 +9258,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));