>From e8c68da28dd3f6b785aa23d4cf3c2973d6bca6c5 Mon Sep 17 00:00:00 2001
From: Petr Jelinek <pjmodos@pjmodos.net>
Date: Mon, 28 Sep 2015 19:43:19 +0200
Subject: [PATCH 2/2] commit_ts-2pcfix

---
 src/backend/access/transam/commit_ts.c |  9 +++++----
 src/backend/access/transam/twophase.c  | 26 +++++++++++++++++++++++++-
 src/backend/access/transam/xact.c      |  3 +++
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 33136e3..cddde30 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -123,10 +123,11 @@ static void WriteSetTimestampXlogRec(TransactionId mainxid, int nsubxids,
  * decision of storing timestamp info for each subxid.
  *
  * The do_xlog parameter tells us whether to include an XLog record of this
- * or not.  Normal path through RecordTransactionCommit() will be related
- * to a transaction commit XLog record, and so should pass "false" here.
- * Other callers probably want to pass true, so that the given values persist
- * in case of crashes.
+ * or not.  Normally, this is called from transaction (both normal and
+ * prepared) commit code and the information will be stored in the transaction
+ * commit XLog record, and so it should pass "false" here. The XLog redo code
+ * should use "false" here as well. Other callers probably want to pass true,
+ * so that the given values persist in case of crashes.
  */
 void
 TransactionTreeSetCommitTsData(TransactionId xid, int nsubxids,
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index d48d101..6e7ede9 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,6 +57,7 @@
 #include "miscadmin.h"
 #include "pg_trace.h"
 #include "pgstat.h"
+#include "replication/origin.h"
 #include "replication/walsender.h"
 #include "replication/syncrep.h"
 #include "storage/fd.h"
@@ -2087,6 +2089,7 @@ RecordTransactionCommitPrepared(TransactionId xid,
 								bool initfileinval)
 {
 	XLogRecPtr	recptr;
+	TimestampTz	committs = GetCurrentTimestamp();
 
 	START_CRIT_SECTION();
 
@@ -2094,13 +2097,34 @@ 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);
 
 	/*
+	 * Record plain commit ts if not replaying remote actions, or if no
+	 * timestamp is configured.
+	 */
+	if (replorigin_session_origin == InvalidRepOriginId ||
+		replorigin_session_origin == DoNotReplicateId ||
+		replorigin_session_origin_timestamp == 0)
+		replorigin_session_origin_timestamp = committs;
+	else
+		replorigin_session_advance(replorigin_session_origin_lsn,
+								   XactLastRecEnd);
+
+	/*
+	 * We don't need to WAL log origin or timestamp here, the commit
+	 * record contains all the necessary information and will redo the SET
+	 * action during replay.
+	 */
+	TransactionTreeSetCommitTsData(xid, nchildren, children,
+								   replorigin_session_origin_timestamp,
+								   replorigin_session_origin, 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
 	 * a contradiction)
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index 068214d..0238771 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -1119,6 +1119,9 @@ AtSubStart_ResourceOwner(void)
  *
  * Returns latest XID among xact and its children, or InvalidTransactionId
  * if the xact has no XID.  (We compute that here just because it's easier.)
+ *
+ * Note: if you change this function you should also look at
+ * RecordTransactionCommitPrepared in twophase.c.
  */
 static TransactionId
 RecordTransactionCommit(void)
-- 
1.9.1

