diff options
Diffstat (limited to 'src/backend/access/transam')
-rw-r--r-- | src/backend/access/transam/parallel.c | 11 | ||||
-rw-r--r-- | src/backend/access/transam/xact.c | 36 |
2 files changed, 43 insertions, 4 deletions
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c index cdaa32e29a4..911da776e80 100644 --- a/src/backend/access/transam/parallel.c +++ b/src/backend/access/transam/parallel.c @@ -87,6 +87,8 @@ typedef struct FixedParallelState PGPROC *parallel_master_pgproc; pid_t parallel_master_pid; BackendId parallel_master_backend_id; + TimestampTz xact_ts; + TimestampTz stmt_ts; /* Mutex protects remaining fields. */ slock_t mutex; @@ -318,6 +320,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(); SpinLockInit(&fps->mutex); fps->last_xlog_end = 0; shm_toc_insert(pcxt->toc, PARALLEL_KEY_FIXED, fps); @@ -1312,6 +1316,13 @@ ParallelWorkerMain(Datum main_arg) return; /* + * 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); + + /* * Identify the entry point to be called. In theory this could result in * loading an additional library, though most likely the entry point is in * the core backend or in a library we just loaded. diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 875be180fe4..e3f668bf6ab 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -675,6 +675,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 @@ -708,11 +724,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); } /* @@ -1867,10 +1889,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); |