Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit58454d0

Browse files
committed
Propagate xactStartTimestamp and stmtStartTimestamp to parallel workers.
Previously, a worker process would establish values for these based onits own start time. In v10 and up, this can trivially be shown to causemisbehavior of transaction_timestamp(), timestamp_in(), and relatedfunctions which are (perhaps unwisely?) marked parallel-safe. It seemslikely that other behaviors might diverge from what happens in the parentas well.It's not as trivial to demonstrate problems in 9.6 or 9.5, but I'm sureit's still possible, so back-patch to all branches containing parallelworker infrastructure.In HEAD only, mark now() and statement_timestamp() as parallel-safe(other affected functions already were). While in theory we couldstill squeeze that change into v11, it doesn't seem important enoughto force a last-minute catversion bump.Konstantin Knizhnik, whacked around a bit by meDiscussion:https://postgr.es/m/6406dbd2-5d37-4cb6-6eb2-9c44172c7e7c@postgrespro.ru
1 parent142cfd3 commit58454d0

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

‎src/backend/access/transam/parallel.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ typedef struct FixedParallelState
7979
PGPROC*parallel_master_pgproc;
8080
pid_tparallel_master_pid;
8181
BackendIdparallel_master_backend_id;
82+
TimestampTzxact_ts;
83+
TimestampTzstmt_ts;
8284

8385
/* Mutex protects remaining fields. */
8486
slock_tmutex;
@@ -289,6 +291,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
289291
fps->parallel_master_pgproc=MyProc;
290292
fps->parallel_master_pid=MyProcPid;
291293
fps->parallel_master_backend_id=MyBackendId;
294+
fps->xact_ts=GetCurrentTransactionStartTimestamp();
295+
fps->stmt_ts=GetCurrentStatementStartTimestamp();
292296
SpinLockInit(&fps->mutex);
293297
fps->last_xlog_end=0;
294298
shm_toc_insert(pcxt->toc,PARALLEL_KEY_FIXED,fps);
@@ -1118,6 +1122,13 @@ ParallelWorkerMain(Datum main_arg)
11181122
fps->parallel_master_pid))
11191123
return;
11201124

1125+
/*
1126+
* Restore transaction and statement start-time timestamps. This must
1127+
* happen before anything that would start a transaction, else asserts in
1128+
* xact.c will fire.
1129+
*/
1130+
SetParallelStartTimestamps(fps->xact_ts,fps->stmt_ts);
1131+
11211132
/*
11221133
* Identify the entry point to be called. In theory this could result in
11231134
* loading an additional library, though most likely the entry point is in

‎src/backend/access/transam/xact.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,22 @@ GetCurrentCommandId(bool used)
701701
returncurrentCommandId;
702702
}
703703

704+
/*
705+
*SetParallelStartTimestamps
706+
*
707+
* In a parallel worker, we should inherit the parent transaction's
708+
* timestamps rather than setting our own. The parallel worker
709+
* infrastructure must call this to provide those values before
710+
* calling StartTransaction() or SetCurrentStatementStartTimestamp().
711+
*/
712+
void
713+
SetParallelStartTimestamps(TimestampTzxact_ts,TimestampTzstmt_ts)
714+
{
715+
Assert(IsParallelWorker());
716+
xactStartTimestamp=xact_ts;
717+
stmtStartTimestamp=stmt_ts;
718+
}
719+
704720
/*
705721
*GetCurrentTransactionStartTimestamp
706722
*/
@@ -735,11 +751,17 @@ GetCurrentTransactionStopTimestamp(void)
735751

736752
/*
737753
*SetCurrentStatementStartTimestamp
754+
*
755+
* In a parallel worker, this should already have been provided by a call
756+
* to SetParallelStartTimestamps().
738757
*/
739758
void
740759
SetCurrentStatementStartTimestamp(void)
741760
{
742-
stmtStartTimestamp=GetCurrentTimestamp();
761+
if (!IsParallelWorker())
762+
stmtStartTimestamp=GetCurrentTimestamp();
763+
else
764+
Assert(stmtStartTimestamp!=0);
743765
}
744766

745767
/*
@@ -1893,10 +1915,16 @@ StartTransaction(void)
18931915
/*
18941916
* set transaction_timestamp() (a/k/a now()). We want this to be the same
18951917
* as the first command's statement_timestamp(), so don't do a fresh
1896-
* GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1897-
* xactStopTimestamp as unset.
1918+
* GetCurrentTimestamp() call (which'd be expensive anyway). In a
1919+
* parallel worker, this should already have been provided by a call to
1920+
* SetParallelStartTimestamps().
1921+
*
1922+
* Also, mark xactStopTimestamp as unset.
18981923
*/
1899-
xactStartTimestamp=stmtStartTimestamp;
1924+
if (!IsParallelWorker())
1925+
xactStartTimestamp=stmtStartTimestamp;
1926+
else
1927+
Assert(xactStartTimestamp!=0);
19001928
xactStopTimestamp=0;
19011929
pgstat_report_xact_timestamp(xactStartTimestamp);
19021930

‎src/include/access/xact.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,7 @@ extern SubTransactionId GetCurrentSubTransactionId(void);
337337
externvoidMarkCurrentTransactionIdLoggedIfAny(void);
338338
externboolSubTransactionIsActive(SubTransactionIdsubxid);
339339
externCommandIdGetCurrentCommandId(boolused);
340+
externvoidSetParallelStartTimestamps(TimestampTzxact_ts,TimestampTzstmt_ts);
340341
externTimestampTzGetCurrentTransactionStartTimestamp(void);
341342
externTimestampTzGetCurrentStatementStartTimestamp(void);
342343
externTimestampTzGetCurrentTransactionStopTimestamp(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp