diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-03-09 17:44:00 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-03-09 17:44:00 -0300 |
commit | 4f3924d9cd438ba4e6fd639460f8c859c65d45a3 (patch) | |
tree | 748f52461ea81ff16239bc156f7950c597eefda0 /src/backend/access/transam/xlog.c | |
parent | e3f1c24b992acb88e4ccf33118640aee4b11dd47 (diff) | |
download | postgresql-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.c | 36 |
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); |