From ffe8c7c677197ef8062a71309b14a1847841118c Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas <heikki.linnakangas@iki.fi> Date: Mon, 3 May 2010 11:17:52 +0000 Subject: [PATCH] Need to hold ControlFileLock while updating control file. Update minRecoveryPoint in control file when replaying a parameter change record, to ensure that we don't allow hot standby on WAL generated without wal_level='hot_standby' after a standby restart. --- src/backend/access/transam/xlog.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 99e53b76321..a39d455a7f0 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.408 2010/05/02 02:10:33 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.409 2010/05/03 11:17:52 heikki Exp $ * *------------------------------------------------------------------------- */ @@ -7920,11 +7920,28 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) /* Update our copy of the parameters in pg_control */ memcpy(&xlrec, XLogRecGetData(record), sizeof(xl_parameter_change)); + LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); ControlFile->MaxConnections = xlrec.MaxConnections; ControlFile->max_prepared_xacts = xlrec.max_prepared_xacts; ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact; ControlFile->wal_level = xlrec.wal_level; + /* + * Update minRecoveryPoint to ensure that if recovery is aborted, + * we recover back up to this point before allowing hot standby + * again. This is particularly important if wal_level was set to + * 'archive' before, and is now 'hot_standby', to ensure you don't + * run queries against the WAL preceding the wal_level change. + * Same applies to decreasing max_* settings. + */ + minRecoveryPoint = ControlFile->minRecoveryPoint; + if ((minRecoveryPoint.xlogid != 0 || minRecoveryPoint.xrecoff != 0) + && XLByteLT(minRecoveryPoint, lsn)) + { + ControlFile->minRecoveryPoint = lsn; + } + UpdateControlFile(); + LWLockRelease(ControlFileLock); /* Check to see if any changes to max_connections give problems */ CheckRequiredParameterValues(); -- GitLab