diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a3e8ce092f..b8f648927a 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -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)) diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 95180b2ef5..e4f8f597c6 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -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 diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 4eb85720a7..46b662266b 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -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(); } diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index 66bfb77295..e0635ab4e6 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -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);