diff options
-rw-r--r-- | src/backend/access/transam/parallel.c | 11 | ||||
-rw-r--r-- | src/backend/access/transam/xact.c | 36 | ||||
-rw-r--r-- | src/include/access/xact.h | 1 |
3 files changed, 44 insertions, 4 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index bf2fbd69982..1c5b4d067fc 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -71,6 +71,8 @@ typedef struct FixedParallelState PGPROC *parallel_master_pgproc; pid_t parallel_master_pid; BackendId parallel_master_backend_id; + TimestampTz xact_ts; + TimestampTz stmt_ts; /* Entrypoint for parallel workers. */ parallel_worker_main_type entrypoint; @@ -282,6 +284,8 @@ InitializeParallelDSM(ParallelContext *pcxt) fps->parallel_master_pgproc = MyProc; fps->parallel_master_pid = MyProcPid; fps->parallel_master_backend_id = MyBackendId; + fps->xact_ts = GetCurrentTransactionStartTimestamp(); + fps->stmt_ts = GetCurrentStatementStartTimestamp(); fps->entrypoint = pcxt->entrypoint; SpinLockInit(&fps->mutex); fps->last_xlog_end = 0; @@ -925,6 +929,13 @@ ParallelWorkerMain(Datum main_arg) */ /* + * Restore transaction and statement start-time timestamps. This must + * happen before anything that would start a transaction, else asserts in + * xact.c will fire. + */ + SetParallelStartTimestamps(fps->xact_ts, fps->stmt_ts); + + /* * Load libraries that were loaded by original backend. We want to do * this before restoring GUCs, because the libraries might define custom * variables. 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); diff --git a/src/include/access/xact.h b/src/include/access/xact.h index b688ad952ad..e0010a4d965 100644 --- a/src/include/access/xact.h +++ b/src/include/access/xact.h @@ -313,6 +313,7 @@ extern SubTransactionId GetCurrentSubTransactionId(void); extern void MarkCurrentTransactionIdLoggedIfAny(void); extern bool SubTransactionIsActive(SubTransactionId subxid); extern CommandId GetCurrentCommandId(bool used); +extern void SetParallelStartTimestamps(TimestampTz xact_ts, TimestampTz stmt_ts); extern TimestampTz GetCurrentTransactionStartTimestamp(void); extern TimestampTz GetCurrentStatementStartTimestamp(void); extern TimestampTz GetCurrentTransactionStopTimestamp(void); |