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

Commitbc062cb

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 parent794025e commitbc062cb

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);
@@ -1260,6 +1271,8 @@ ParallelWorkerMain(Datum main_arg)
12601271
char*enumblacklistspace;
12611272
StringInfoDatamsgbuf;
12621273
char*session_dsm_handle_space;
1274+
Snapshottsnapshot;
1275+
Snapshotasnapshot;
12631276

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

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

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

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp