Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Perform only one ReadControlFile() during startup.
authorAndres Freund <andres@anarazel.de>
Wed, 13 Sep 2017 09:12:17 +0000 (02:12 -0700)
committerAndres Freund <andres@anarazel.de>
Thu, 14 Sep 2017 21:14:34 +0000 (14:14 -0700)
Previously we read the control file in multiple places. But soon the
segment size will be configurable and stored in the control file, and
that needs to be available earlier than it currently is needed.

Instead of adding yet another place where it's read, refactor things
so there's a single processing of the control file during startup (in
EXEC_BACKEND that's every individual backend's startup).

Author: Andres Freund
Discussion: http://postgr.es/m/20170913092828.aozd3gvvmw67gmyc@alap3.anarazel.de

src/backend/access/transam/xlog.c
src/backend/postmaster/postmaster.c
src/backend/tcop/postgres.c
src/include/access/xlog.h

index a3e8ce092fa5d37695d2167ecb114929cabb4140..b8f648927a21c18d8eb8c8cf88087cefc4813c6b 100644 (file)
@@ -4799,6 +4799,22 @@ check_wal_buffers(int *newval, void **extra, GucSource source)
    return true;
 }
 
+/*
+ * Read the control file, set respective GUCs.
+ *
+ * This is to be called during startup, unless in bootstrap mode, where no
+ * control file yet exists.  As there's no shared memory yet (its sizing can
+ * depend on the contents of the control file!), first store data in local
+ * memory. XLOGShemInit() will then copy it to shared memory later.
+ */
+void
+LocalProcessControlFile(void)
+{
+   Assert(ControlFile == NULL);
+   ControlFile = palloc(sizeof(ControlFileData));
+   ReadControlFile();
+}
+
 /*
  * Initialization of shared memory for XLOG
  */
@@ -4850,6 +4866,7 @@ XLOGShmemInit(void)
                foundXLog;
    char       *allocptr;
    int         i;
+   ControlFileData *localControlFile;
 
 #ifdef WAL_DEBUG
 
@@ -4867,8 +4884,18 @@ XLOGShmemInit(void)
    }
 #endif
 
+   /*
+    * Already have read control file locally, unless in bootstrap mode. Move
+    * local version into shared memory.
+    */
+   localControlFile = ControlFile;
    ControlFile = (ControlFileData *)
        ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
+   if (localControlFile)
+   {
+       memcpy(ControlFile, localControlFile, sizeof(ControlFileData));
+       pfree(localControlFile);
+   }
    XLogCtl = (XLogCtlData *)
        ShmemInitStruct("XLOG Ctl", XLOGShmemSize(), &foundXLog);
 
@@ -4933,14 +4960,6 @@ XLOGShmemInit(void)
    SpinLockInit(&XLogCtl->info_lck);
    SpinLockInit(&XLogCtl->ulsn_lck);
    InitSharedLatch(&XLogCtl->recoveryWakeupLatch);
-
-   /*
-    * If we are not in bootstrap mode, pg_control should already exist. Read
-    * and validate it immediately (see comments in ReadControlFile() for the
-    * reasons why).
-    */
-   if (!IsBootstrapProcessingMode())
-       ReadControlFile();
 }
 
 /*
@@ -5129,6 +5148,12 @@ BootStrapXLOG(void)
    BootStrapMultiXact();
 
    pfree(buffer);
+
+   /*
+    * Force control file to be read - in contrast to normal processing we'd
+    * otherwise never run the checks and GUC related initializations therein.
+    */
+   ReadControlFile();
 }
 
 static char *
@@ -6227,13 +6252,8 @@ StartupXLOG(void)
    struct stat st;
 
    /*
-    * Read control file and check XLOG status looks valid.
-    *
-    * Note: in most control paths, *ControlFile is already valid and we need
-    * not do ReadControlFile() here, but might as well do it to be sure.
+    * Verify XLOG status looks valid.
     */
-   ReadControlFile();
-
    if (ControlFile->state < DB_SHUTDOWNED ||
        ControlFile->state > DB_IN_PRODUCTION ||
        !XRecOffIsValid(ControlFile->checkPoint))
index 95180b2ef5977682efb442673890d2ce719f1ff5..e4f8f597c6060cddc7cf6aa656937910e279d607 100644 (file)
@@ -950,6 +950,9 @@ PostmasterMain(int argc, char *argv[])
     */
    CreateDataDirLockFile(true);
 
+   /* read control file (error checking and contains config) */
+   LocalProcessControlFile();
+
    /*
     * Initialize SSL library, if specified.
     */
@@ -4805,6 +4808,9 @@ SubPostmasterMain(int argc, char *argv[])
    /* Read in remaining GUC variables */
    read_nondefault_variables();
 
+   /* (re-)read control file (contains config) */
+   LocalProcessControlFile();
+
    /*
     * Reload any libraries that were preloaded by the postmaster.  Since we
     * exec'd this process, those libraries didn't come along with us; but we
index 4eb85720a749d419bf76a260b6a5d1d287407027..46b662266b56085355567769c68657935e7ece5a 100644 (file)
@@ -3717,6 +3717,9 @@ PostgresMain(int argc, char *argv[],
         */
        CreateDataDirLockFile(false);
 
+       /* read control file (error checking and contains config ) */
+       LocalProcessControlFile();
+
        /* Initialize MaxBackends (if under postmaster, was done already) */
        InitializeMaxBackends();
    }
index 66bfb77295b17ade31a4b655a61a5caf4c23e283..e0635ab4e68a4146d0ebad4bf86ff01dba60a6d7 100644 (file)
@@ -261,6 +261,7 @@ extern XLogRecPtr GetFakeLSNForUnloggedRel(void);
 extern Size XLOGShmemSize(void);
 extern void XLOGShmemInit(void);
 extern void BootStrapXLOG(void);
+extern void LocalProcessControlFile(void);
 extern void StartupXLOG(void);
 extern void ShutdownXLOG(int code, Datum arg);
 extern void InitXLOGAccess(void);