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

Commit6bf278d

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 parentc905b67 commit6bf278d

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
@@ -86,6 +86,8 @@ typedef struct FixedParallelState
8686
PGPROC*parallel_master_pgproc;
8787
pid_tparallel_master_pid;
8888
BackendIdparallel_master_backend_id;
89+
TimestampTzxact_ts;
90+
TimestampTzstmt_ts;
8991

9092
/* Mutex protects remaining fields. */
9193
slock_tmutex;
@@ -321,6 +323,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
321323
fps->parallel_master_pgproc=MyProc;
322324
fps->parallel_master_pid=MyProcPid;
323325
fps->parallel_master_backend_id=MyBackendId;
326+
fps->xact_ts=GetCurrentTransactionStartTimestamp();
327+
fps->stmt_ts=GetCurrentStatementStartTimestamp();
324328
SpinLockInit(&fps->mutex);
325329
fps->last_xlog_end=0;
326330
shm_toc_insert(pcxt->toc,PARALLEL_KEY_FIXED,fps);
@@ -1303,6 +1307,13 @@ ParallelWorkerMain(Datum main_arg)
13031307
fps->parallel_master_pid))
13041308
return;
13051309

1310+
/*
1311+
* Restore transaction and statement start-time timestamps. This must
1312+
* happen before anything that would start a transaction, else asserts in
1313+
* xact.c will fire.
1314+
*/
1315+
SetParallelStartTimestamps(fps->xact_ts,fps->stmt_ts);
1316+
13061317
/*
13071318
* Identify the entry point to be called. In theory this could result in
13081319
* 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
@@ -693,6 +693,22 @@ GetCurrentCommandId(bool used)
693693
returncurrentCommandId;
694694
}
695695

696+
/*
697+
*SetParallelStartTimestamps
698+
*
699+
* In a parallel worker, we should inherit the parent transaction's
700+
* timestamps rather than setting our own. The parallel worker
701+
* infrastructure must call this to provide those values before
702+
* calling StartTransaction() or SetCurrentStatementStartTimestamp().
703+
*/
704+
void
705+
SetParallelStartTimestamps(TimestampTzxact_ts,TimestampTzstmt_ts)
706+
{
707+
Assert(IsParallelWorker());
708+
xactStartTimestamp=xact_ts;
709+
stmtStartTimestamp=stmt_ts;
710+
}
711+
696712
/*
697713
*GetCurrentTransactionStartTimestamp
698714
*/
@@ -727,11 +743,17 @@ GetCurrentTransactionStopTimestamp(void)
727743

728744
/*
729745
*SetCurrentStatementStartTimestamp
746+
*
747+
* In a parallel worker, this should already have been provided by a call
748+
* to SetParallelStartTimestamps().
730749
*/
731750
void
732751
SetCurrentStatementStartTimestamp(void)
733752
{
734-
stmtStartTimestamp=GetCurrentTimestamp();
753+
if (!IsParallelWorker())
754+
stmtStartTimestamp=GetCurrentTimestamp();
755+
else
756+
Assert(stmtStartTimestamp!=0);
735757
}
736758

737759
/*
@@ -1886,10 +1908,16 @@ StartTransaction(void)
18861908
/*
18871909
* set transaction_timestamp() (a/k/a now()). We want this to be the same
18881910
* as the first command's statement_timestamp(), so don't do a fresh
1889-
* GetCurrentTimestamp() call (which'd be expensive anyway). Also, mark
1890-
* xactStopTimestamp as unset.
1911+
* GetCurrentTimestamp() call (which'd be expensive anyway). In a
1912+
* parallel worker, this should already have been provided by a call to
1913+
* SetParallelStartTimestamps().
1914+
*
1915+
* Also, mark xactStopTimestamp as unset.
18911916
*/
1892-
xactStartTimestamp=stmtStartTimestamp;
1917+
if (!IsParallelWorker())
1918+
xactStartTimestamp=stmtStartTimestamp;
1919+
else
1920+
Assert(xactStartTimestamp!=0);
18931921
xactStopTimestamp=0;
18941922
pgstat_report_xact_timestamp(xactStartTimestamp);
18951923

‎src/include/access/xact.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ extern SubTransactionId GetCurrentSubTransactionId(void);
359359
externvoidMarkCurrentTransactionIdLoggedIfAny(void);
360360
externboolSubTransactionIsActive(SubTransactionIdsubxid);
361361
externCommandIdGetCurrentCommandId(boolused);
362+
externvoidSetParallelStartTimestamps(TimestampTzxact_ts,TimestampTzstmt_ts);
362363
externTimestampTzGetCurrentTransactionStartTimestamp(void);
363364
externTimestampTzGetCurrentStatementStartTimestamp(void);
364365
externTimestampTzGetCurrentTransactionStopTimestamp(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp