summaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xact.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2018-10-06 12:00:10 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2018-10-06 12:00:10 -0400
commit3c9dd963cec6d4c314bccf74256acc893108a4be (patch)
treec170e73d54ab7ebce8dceadb45626df0da21e125 /src/backend/access/transam/xact.c
parent0dc6bf633a2857294cd0d1b9a74c7f49836d5898 (diff)
Propagate xactStartTimestamp and stmtStartTimestamp to parallel workers.
Previously, a worker process would establish values for these based on its own start time. In v10 and up, this can trivially be shown to cause misbehavior of transaction_timestamp(), timestamp_in(), and related functions which are (perhaps unwisely?) marked parallel-safe. It seems likely that other behaviors might diverge from what happens in the parent as well. It's not as trivial to demonstrate problems in 9.6 or 9.5, but I'm sure it's still possible, so back-patch to all branches containing parallel worker infrastructure. In HEAD only, mark now() and statement_timestamp() as parallel-safe (other affected functions already were). While in theory we could still squeeze that change into v11, it doesn't seem important enough to force a last-minute catversion bump. Konstantin Knizhnik, whacked around a bit by me Discussion: https://postgr.es/m/6406dbd2-5d37-4cb6-6eb2-9c44172c7e7c@postgrespro.ru
Diffstat (limited to 'src/backend/access/transam/xact.c')
-rw-r--r--src/backend/access/transam/xact.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index d3632c25cae..bda98e7924a 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -699,6 +699,22 @@ GetCurrentCommandId(bool used)
}
/*
+ * SetParallelStartTimestamps
+ *
+ * In a parallel worker, we should inherit the parent transaction's
+ * timestamps rather than setting our own. The parallel worker
+ * infrastructure must call this to provide those values before
+ * calling StartTransaction() or SetCurrentStatementStartTimestamp().
+ */
+void
+SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts)
+{
+ Assert(IsParallelWorker());
+ xactStartTimestamp = xact_ts;
+ stmtStartTimestamp = stmt_ts;
+}
+
+/*
* GetCurrentTransactionStartTimestamp
*/
TimestampTz
@@ -732,11 +748,17 @@ GetCurrentTransactionStopTimestamp(void)
/*
* SetCurrentStatementStartTimestamp
+ *
+ * In a parallel worker, this should already have been provided by a call
+ * to SetParallelStartTimestamps().
*/
void
SetCurrentStatementStartTimestamp(void)
{
- stmtStartTimestamp = GetCurrentTimestamp();
+ if (!IsParallelWorker())
+ stmtStartTimestamp = GetCurrentTimestamp();
+ else
+ Assert(stmtStartTimestamp != 0);
}
/*
@@ -1875,10 +1897,16 @@ StartTransaction(void)
/*
* set transaction_timestamp() (a/k/a now()). We want this to be the same
* as the first command's statement_timestamp(), so don't do a fresh
- * GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
- * xactStopTimestamp as unset.
+ * GetCurrentTimestamp() call (which'd be expensive anyway). In a
+ * parallel worker, this should already have been provided by a call to
+ * SetParallelStartTimestamps().
+ *
+ * Also, mark xactStopTimestamp as unset.
*/
- xactStartTimestamp = stmtStartTimestamp;
+ if (!IsParallelWorker())
+ xactStartTimestamp = stmtStartTimestamp;
+ else
+ Assert(xactStartTimestamp != 0);
xactStopTimestamp = 0;
pgstat_report_xact_timestamp(xactStartTimestamp);