diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-09-29 14:40:56 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-09-29 14:40:56 -0300 |
commit | 6b61955135e94b39d85571fdbb0c5a749af767f1 (patch) | |
tree | edf10d08cad9655c02bb3dc2e5ed5bcc53be8831 /src/backend/access/transam/twophase.c | |
parent | b631a46ed83b7eebf5cde16b41d842596cbcc69d (diff) |
Code review for transaction commit timestamps
There are three main changes here:
1. No longer cause a start failure in a standby if the feature is
disabled in postgresql.conf but enabled in the master. This reverts one
part of commit 4f3924d9cd43; what we keep is the ability of the standby
to activate/deactivate the module (which includes creating and removing
segments as appropriate) during replay of such actions in the master.
2. Replay WAL records affecting commitTS even if the feature is
disabled. This means the standby will always have the same state as the
master after replay.
3. Have COMMIT PREPARE record the transaction commit time as well. We
were previously only applying it in the normal transaction commit path.
Author: Petr JelĂnek
Discussion: http://www.postgresql.org/message-id/CAHGQGwHereDzzzmfxEBYcVQu3oZv6vZcgu1TPeERWbDc+gQ06g@mail.gmail.com
Discussion: http://www.postgresql.org/message-id/CAHGQGwFuzfO4JscM9LCAmCDCxp_MfLvN4QdB+xWsS-FijbjTYQ@mail.gmail.com
Additionally, I cleaned up nearby code related to replication origins,
which I found a bit hard to follow, and fixed a couple of typos.
Backpatch to 9.5, where this code was introduced.
Per bug reports from Fujii Masao and subsequent discussion.
Diffstat (limited to 'src/backend/access/transam/twophase.c')
-rw-r--r-- | src/backend/access/transam/twophase.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index d48d101340f..e005cc558ab 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -41,6 +41,7 @@ #include <time.h> #include <unistd.h> +#include "access/commit_ts.h" #include "access/htup_details.h" #include "access/subtrans.h" #include "access/transam.h" @@ -56,8 +57,9 @@ #include "miscadmin.h" #include "pg_trace.h" #include "pgstat.h" -#include "replication/walsender.h" +#include "replication/origin.h" #include "replication/syncrep.h" +#include "replication/walsender.h" #include "storage/fd.h" #include "storage/ipc.h" #include "storage/predicate.h" @@ -2070,8 +2072,9 @@ RecoverPreparedTransactions(void) /* * RecordTransactionCommitPrepared * - * This is basically the same as RecordTransactionCommit: in particular, - * we must set the delayChkpt flag to avoid a race condition. + * This is basically the same as RecordTransactionCommit (q.v. if you change + * this function): in particular, we must set the delayChkpt flag to avoid a + * race condition. * * We know the transaction made at least one XLOG entry (its PREPARE), * so it is never possible to optimize out the commit record. @@ -2087,6 +2090,15 @@ RecordTransactionCommitPrepared(TransactionId xid, bool initfileinval) { XLogRecPtr recptr; + TimestampTz committs = GetCurrentTimestamp(); + bool replorigin; + + /* + * Are we using the replication origins feature? Or, in other words, are + * we replaying remote actions? + */ + replorigin = (replorigin_session_origin != InvalidRepOriginId && + replorigin_session_origin != DoNotReplicateId); START_CRIT_SECTION(); @@ -2094,12 +2106,33 @@ RecordTransactionCommitPrepared(TransactionId xid, MyPgXact->delayChkpt = true; /* Emit the XLOG commit record */ - recptr = XactLogCommitRecord(GetCurrentTimestamp(), + recptr = XactLogCommitRecord(committs, nchildren, children, nrels, rels, ninvalmsgs, invalmsgs, initfileinval, false, xid); + + if (replorigin) + /* Move LSNs forward for this replication origin */ + replorigin_session_advance(replorigin_session_origin_lsn, + XactLastRecEnd); + + /* + * Record commit timestamp. The value comes from plain commit timestamp + * if replorigin is not enabled, or replorigin already set a value for us + * in replorigin_session_origin_timestamp otherwise. + * + * We don't need to WAL-log anything here, as the commit record written + * above already contains the data. + */ + if (!replorigin || replorigin_session_origin_timestamp == 0) + replorigin_session_origin_timestamp = committs; + + TransactionTreeSetCommitTsData(xid, nchildren, children, + replorigin_session_origin_timestamp, + replorigin_session_origin, false, false); + /* * We don't currently try to sleep before flush here ... nor is there any * support for async commit of a prepared xact (the very idea is probably |