aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
authorAlvaro Herrera <alvherre@alvh.no-ip.org>2015-03-09 17:44:00 -0300
committerAlvaro Herrera <alvherre@alvh.no-ip.org>2015-03-09 17:44:00 -0300
commit4f3924d9cd438ba4e6fd639460f8c859c65d45a3 (patch)
tree748f52461ea81ff16239bc156f7950c597eefda0 /src/backend/access/transam/xlog.c
parente3f1c24b992acb88e4ccf33118640aee4b11dd47 (diff)
downloadpostgresql-4f3924d9cd438ba4e6fd639460f8c859c65d45a3.tar.gz
postgresql-4f3924d9cd438ba4e6fd639460f8c859c65d45a3.zip
Keep CommitTs module in sync in standby and master
We allow this module to be turned off on restarts, so a restart time check is enough to activate or deactivate the module; however, if there is a standby replaying WAL emitted from a master which is restarted, but the standby isn't, the state in the standby becomes inconsistent and can easily be crashed. Fix by activating and deactivating the module during WAL replay on parameter change as well as on system start. Problem reported by Fujii Masao in http://www.postgresql.org/message-id/CAHGQGwFhJ3CnHo1CELEfay18yg_RA-XZT-7D8NuWUoYSZ90r4Q@mail.gmail.com Author: Petr JelĂ­nek
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r--src/backend/access/transam/xlog.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index a28155f977d..71cbe0ef687 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5688,6 +5688,19 @@ do { \
minValue))); \
} while(0)
+#define RecoveryRequiresBoolParameter(param_name, currValue, masterValue) \
+do { \
+ bool _currValue = (currValue); \
+ bool _masterValue = (masterValue); \
+ if (_currValue != _masterValue) \
+ ereport(ERROR, \
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE), \
+ errmsg("hot standby is not possible because it requires \"%s\" to be same on master and standby (master has \"%s\", standby has \"%s\")", \
+ param_name, \
+ _masterValue ? "true" : "false", \
+ _currValue ? "true" : "false"))); \
+} while(0)
+
/*
* Check to see if required parameters are set high enough on this server
* for various aspects of recovery operation.
@@ -5730,6 +5743,9 @@ CheckRequiredParameterValues(void)
RecoveryRequiresIntParameter("max_locks_per_transaction",
max_locks_per_xact,
ControlFile->max_locks_per_xact);
+ RecoveryRequiresBoolParameter("track_commit_timestamp",
+ track_commit_timestamp,
+ ControlFile->track_commit_timestamp);
}
}
@@ -9118,7 +9134,6 @@ xlog_redo(XLogReaderState *record)
ControlFile->max_locks_per_xact = xlrec.max_locks_per_xact;
ControlFile->wal_level = xlrec.wal_level;
ControlFile->wal_log_hints = xlrec.wal_log_hints;
- ControlFile->track_commit_timestamp = xlrec.track_commit_timestamp;
/*
* Update minRecoveryPoint to ensure that if recovery is aborted, we
@@ -9136,6 +9151,25 @@ xlog_redo(XLogReaderState *record)
ControlFile->minRecoveryPointTLI = ThisTimeLineID;
}
+ /*
+ * Update the commit timestamp tracking. If there was a change
+ * it needs to be activated or deactivated accordingly.
+ */
+ if (track_commit_timestamp != xlrec.track_commit_timestamp)
+ {
+ track_commit_timestamp = xlrec.track_commit_timestamp;
+ ControlFile->track_commit_timestamp = track_commit_timestamp;
+ if (track_commit_timestamp)
+ ActivateCommitTs();
+ else
+ /*
+ * We can't create a new WAL record here, but that's OK as
+ * master did the WAL logging already and we will replay the
+ * record from master in case we crash.
+ */
+ DeactivateCommitTs(false);
+ }
+
UpdateControlFile();
LWLockRelease(ControlFileLock);