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

Commita780b2f

Browse files
committed
Fix broken snapshot handling in parallel workers.
Pengchengliu reported an assertion failure in a parallel woker whileperforming a parallel scan using an overflowed snapshot. The proximatecause is that TransactionXmin was set to an incorrect value. Theunderlying cause is incorrect snapshot handling in parallel.c.In particular, InitializeParallelDSM() was unconditionally callingGetTransactionSnapshot(), because I (rhaas) mistakenly thought thatwas always retrieving an existing snapshot whereas, at isolationlevels less than REPEATABLE READ, it's actually taking a new one. Soinstead do this only at higher isolation levels where there actuallyis a single snapshot for the whole transaction.By itself, this is not a sufficient fix, because we still need toguarantee that TransactionXmin gets set properly in the workers. Theeasiest way to do that seems to be to install the leader's activesnapshot as the transaction snapshot if the leader did not serialize atransaction snapshot. This doesn't affect the results of futureGetTrasnactionSnapshot() calls since those have to take a new snapshotanyway; what we care about is the side effect of setting TransactionXmin.Report by Pengchengliu. Patch by Greg Nancarrow, except for some commenttext which I supplied.Discussion:https://postgr.es/m/002f01d748ac$eaa781a0$bff684e0$@tju.edu.cn
1 parent43d4dd8 commita780b2f

File tree

1 file changed

+38
-14
lines changed

1 file changed

+38
-14
lines changed

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

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,11 @@ InitializeParallelDSM(ParallelContext *pcxt)
254254
shm_toc_estimate_chunk(&pcxt->estimator,guc_len);
255255
combocidlen=EstimateComboCIDStateSpace();
256256
shm_toc_estimate_chunk(&pcxt->estimator,combocidlen);
257-
tsnaplen=EstimateSnapshotSpace(transaction_snapshot);
258-
shm_toc_estimate_chunk(&pcxt->estimator,tsnaplen);
257+
if (IsolationUsesXactSnapshot())
258+
{
259+
tsnaplen=EstimateSnapshotSpace(transaction_snapshot);
260+
shm_toc_estimate_chunk(&pcxt->estimator,tsnaplen);
261+
}
259262
asnaplen=EstimateSnapshotSpace(active_snapshot);
260263
shm_toc_estimate_chunk(&pcxt->estimator,asnaplen);
261264
tstatelen=EstimateTransactionStateSpace();
@@ -366,11 +369,19 @@ InitializeParallelDSM(ParallelContext *pcxt)
366369
SerializeComboCIDState(combocidlen,combocidspace);
367370
shm_toc_insert(pcxt->toc,PARALLEL_KEY_COMBO_CID,combocidspace);
368371

369-
/* Serialize transaction snapshot and active snapshot. */
370-
tsnapspace=shm_toc_allocate(pcxt->toc,tsnaplen);
371-
SerializeSnapshot(transaction_snapshot,tsnapspace);
372-
shm_toc_insert(pcxt->toc,PARALLEL_KEY_TRANSACTION_SNAPSHOT,
373-
tsnapspace);
372+
/*
373+
* Serialize the transaction snapshot if the transaction
374+
* isolation-level uses a transaction snapshot.
375+
*/
376+
if (IsolationUsesXactSnapshot())
377+
{
378+
tsnapspace=shm_toc_allocate(pcxt->toc,tsnaplen);
379+
SerializeSnapshot(transaction_snapshot,tsnapspace);
380+
shm_toc_insert(pcxt->toc,PARALLEL_KEY_TRANSACTION_SNAPSHOT,
381+
tsnapspace);
382+
}
383+
384+
/* Serialize the active snapshot. */
374385
asnapspace=shm_toc_allocate(pcxt->toc,asnaplen);
375386
SerializeSnapshot(active_snapshot,asnapspace);
376387
shm_toc_insert(pcxt->toc,PARALLEL_KEY_ACTIVE_SNAPSHOT,asnapspace);
@@ -1261,6 +1272,8 @@ ParallelWorkerMain(Datum main_arg)
12611272
char*uncommittedenumsspace;
12621273
StringInfoDatamsgbuf;
12631274
char*session_dsm_handle_space;
1275+
Snapshottsnapshot;
1276+
Snapshotasnapshot;
12641277

12651278
/* Set flag to indicate that we're initializing a parallel worker. */
12661279
InitializingParallelWorker= true;
@@ -1408,14 +1421,25 @@ ParallelWorkerMain(Datum main_arg)
14081421
shm_toc_lookup(toc,PARALLEL_KEY_SESSION_DSM, false);
14091422
AttachSession(*(dsm_handle*)session_dsm_handle_space);
14101423

1411-
/* Restore transaction snapshot. */
1412-
tsnapspace=shm_toc_lookup(toc,PARALLEL_KEY_TRANSACTION_SNAPSHOT, false);
1413-
RestoreTransactionSnapshot(RestoreSnapshot(tsnapspace),
1414-
fps->parallel_leader_pgproc);
1415-
1416-
/* Restore active snapshot. */
1424+
/*
1425+
* If the transaction isolation level is REPEATABLE READ or SERIALIZABLE,
1426+
* the leader has serialized the transaction snapshot and we must restore
1427+
* it. At lower isolation levels, there is no transaction-lifetime
1428+
* snapshot, but we need TransactionXmin to get set to a value which is
1429+
* less than or equal to the xmin of every snapshot that will be used by
1430+
* this worker. The easiest way to accomplish that is to install the
1431+
* active snapshot as the transaction snapshot. Code running in this
1432+
* parallel worker might take new snapshots via GetTransactionSnapshot()
1433+
* or GetLatestSnapshot(), but it shouldn't have any way of acquiring a
1434+
* snapshot older than the active snapshot.
1435+
*/
14171436
asnapspace=shm_toc_lookup(toc,PARALLEL_KEY_ACTIVE_SNAPSHOT, false);
1418-
PushActiveSnapshot(RestoreSnapshot(asnapspace));
1437+
tsnapspace=shm_toc_lookup(toc,PARALLEL_KEY_TRANSACTION_SNAPSHOT, true);
1438+
asnapshot=RestoreSnapshot(asnapspace);
1439+
tsnapshot=tsnapspace ?RestoreSnapshot(tsnapspace) :asnapshot;
1440+
RestoreTransactionSnapshot(tsnapshot,
1441+
fps->parallel_leader_pgproc);
1442+
PushActiveSnapshot(asnapshot);
14191443

14201444
/*
14211445
* We've changed which tuples we can see, and must therefore invalidate

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp