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

Commit7cb7122

Browse files
Remove O(N^2) performance issue with multiple SAVEPOINTs.
Subtransaction locks now released en masse at main commit, rather thanrepeatedly re-scanning for locks as we ascend the nested transaction tree.Split transaction state TBLOCK_SUBEND into two states, TBLOCK_SUBCOMMITand TBLOCK_SUBRELEASE to allow the commit path to be optimised usingthe existing code in ResourceOwnerRelease() which appears to have beenintended for this usage, judging from comments therein.
1 parent8e5ac74 commit7cb7122

File tree

1 file changed

+70
-32
lines changed
  • src/backend/access/transam

1 file changed

+70
-32
lines changed

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

Lines changed: 70 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ typedef enum TBlockState
118118
/* subtransaction states */
119119
TBLOCK_SUBBEGIN,/* starting a subtransaction */
120120
TBLOCK_SUBINPROGRESS,/* live subtransaction */
121-
TBLOCK_SUBEND,/* RELEASE received */
121+
TBLOCK_SUBRELEASE,/* RELEASE received */
122+
TBLOCK_SUBCOMMIT,/* COMMIT received while TBLOCK_SUBINPROGRESS */
122123
TBLOCK_SUBABORT,/* failed subxact, awaiting ROLLBACK */
123124
TBLOCK_SUBABORT_END,/* failed subxact, ROLLBACK received */
124125
TBLOCK_SUBABORT_PENDING,/* live subxact, ROLLBACK received */
@@ -272,7 +273,7 @@ static TransactionId RecordTransactionAbort(bool isSubXact);
272273
staticvoidStartTransaction(void);
273274

274275
staticvoidStartSubTransaction(void);
275-
staticvoidCommitSubTransaction(void);
276+
staticvoidCommitSubTransaction(boolisTopLevel);
276277
staticvoidAbortSubTransaction(void);
277278
staticvoidCleanupSubTransaction(void);
278279
staticvoidPushTransaction(void);
@@ -2442,7 +2443,8 @@ StartTransactionCommand(void)
24422443
caseTBLOCK_BEGIN:
24432444
caseTBLOCK_SUBBEGIN:
24442445
caseTBLOCK_END:
2445-
caseTBLOCK_SUBEND:
2446+
caseTBLOCK_SUBRELEASE:
2447+
caseTBLOCK_SUBCOMMIT:
24462448
caseTBLOCK_ABORT_END:
24472449
caseTBLOCK_SUBABORT_END:
24482450
caseTBLOCK_ABORT_PENDING:
@@ -2572,17 +2574,32 @@ CommitTransactionCommand(void)
25722574
break;
25732575

25742576
/*
2575-
* We were issued aCOMMIT orRELEASE command, so we end the
2577+
* We were issued a RELEASE command, so we end the
25762578
* current subtransaction and return to the parent transaction.
2577-
* The parent might be ended too, so repeat till weare all the
2578-
*way out orfind an INPROGRESS transaction.
2579+
* The parent might be ended too, so repeat till wefind an
2580+
*INPROGRESS transaction orsubtransaction.
25792581
*/
2580-
caseTBLOCK_SUBEND:
2582+
caseTBLOCK_SUBRELEASE:
25812583
do
25822584
{
2583-
CommitSubTransaction();
2585+
CommitSubTransaction(false);
25842586
s=CurrentTransactionState;/* changed by pop */
2585-
}while (s->blockState==TBLOCK_SUBEND);
2587+
}while (s->blockState==TBLOCK_SUBRELEASE);
2588+
2589+
Assert(s->blockState==TBLOCK_INPROGRESS||
2590+
s->blockState==TBLOCK_SUBINPROGRESS);
2591+
break;
2592+
2593+
/*
2594+
* We were issued a COMMIT, so we end the current subtransaction
2595+
* hierarchy and perform final commit.
2596+
*/
2597+
caseTBLOCK_SUBCOMMIT:
2598+
do
2599+
{
2600+
CommitSubTransaction(true);
2601+
s=CurrentTransactionState;/* changed by pop */
2602+
}while (s->blockState==TBLOCK_SUBCOMMIT);
25862603
/* If we had a COMMIT command, finish off the main xact too */
25872604
if (s->blockState==TBLOCK_END)
25882605
{
@@ -2597,10 +2614,8 @@ CommitTransactionCommand(void)
25972614
s->blockState=TBLOCK_DEFAULT;
25982615
}
25992616
else
2600-
{
2601-
Assert(s->blockState==TBLOCK_INPROGRESS||
2602-
s->blockState==TBLOCK_SUBINPROGRESS);
2603-
}
2617+
elog(ERROR,"CommitTransactionCommand: unexpected state %s",
2618+
BlockStateAsString(s->blockState));
26042619
break;
26052620

26062621
/*
@@ -2814,7 +2829,8 @@ AbortCurrentTransaction(void)
28142829
* applies if we get a failure while ending a subtransaction.
28152830
*/
28162831
caseTBLOCK_SUBBEGIN:
2817-
caseTBLOCK_SUBEND:
2832+
caseTBLOCK_SUBRELEASE:
2833+
caseTBLOCK_SUBCOMMIT:
28182834
caseTBLOCK_SUBABORT_PENDING:
28192835
caseTBLOCK_SUBRESTART:
28202836
AbortSubTransaction();
@@ -3122,7 +3138,8 @@ BeginTransactionBlock(void)
31223138
caseTBLOCK_BEGIN:
31233139
caseTBLOCK_SUBBEGIN:
31243140
caseTBLOCK_END:
3125-
caseTBLOCK_SUBEND:
3141+
caseTBLOCK_SUBRELEASE:
3142+
caseTBLOCK_SUBCOMMIT:
31263143
caseTBLOCK_ABORT_END:
31273144
caseTBLOCK_SUBABORT_END:
31283145
caseTBLOCK_ABORT_PENDING:
@@ -3232,7 +3249,7 @@ EndTransactionBlock(void)
32323249
while (s->parent!=NULL)
32333250
{
32343251
if (s->blockState==TBLOCK_SUBINPROGRESS)
3235-
s->blockState=TBLOCK_SUBEND;
3252+
s->blockState=TBLOCK_SUBCOMMIT;
32363253
else
32373254
elog(FATAL,"EndTransactionBlock: unexpected state %s",
32383255
BlockStateAsString(s->blockState));
@@ -3290,7 +3307,8 @@ EndTransactionBlock(void)
32903307
caseTBLOCK_BEGIN:
32913308
caseTBLOCK_SUBBEGIN:
32923309
caseTBLOCK_END:
3293-
caseTBLOCK_SUBEND:
3310+
caseTBLOCK_SUBRELEASE:
3311+
caseTBLOCK_SUBCOMMIT:
32943312
caseTBLOCK_ABORT_END:
32953313
caseTBLOCK_SUBABORT_END:
32963314
caseTBLOCK_ABORT_PENDING:
@@ -3382,7 +3400,8 @@ UserAbortTransactionBlock(void)
33823400
caseTBLOCK_BEGIN:
33833401
caseTBLOCK_SUBBEGIN:
33843402
caseTBLOCK_END:
3385-
caseTBLOCK_SUBEND:
3403+
caseTBLOCK_SUBRELEASE:
3404+
caseTBLOCK_SUBCOMMIT:
33863405
caseTBLOCK_ABORT_END:
33873406
caseTBLOCK_SUBABORT_END:
33883407
caseTBLOCK_ABORT_PENDING:
@@ -3427,7 +3446,8 @@ DefineSavepoint(char *name)
34273446
caseTBLOCK_BEGIN:
34283447
caseTBLOCK_SUBBEGIN:
34293448
caseTBLOCK_END:
3430-
caseTBLOCK_SUBEND:
3449+
caseTBLOCK_SUBRELEASE:
3450+
caseTBLOCK_SUBCOMMIT:
34313451
caseTBLOCK_ABORT:
34323452
caseTBLOCK_SUBABORT:
34333453
caseTBLOCK_ABORT_END:
@@ -3483,7 +3503,8 @@ ReleaseSavepoint(List *options)
34833503
caseTBLOCK_BEGIN:
34843504
caseTBLOCK_SUBBEGIN:
34853505
caseTBLOCK_END:
3486-
caseTBLOCK_SUBEND:
3506+
caseTBLOCK_SUBRELEASE:
3507+
caseTBLOCK_SUBCOMMIT:
34873508
caseTBLOCK_ABORT:
34883509
caseTBLOCK_SUBABORT:
34893510
caseTBLOCK_ABORT_END:
@@ -3534,7 +3555,7 @@ ReleaseSavepoint(List *options)
35343555
for (;;)
35353556
{
35363557
Assert(xact->blockState==TBLOCK_SUBINPROGRESS);
3537-
xact->blockState=TBLOCK_SUBEND;
3558+
xact->blockState=TBLOCK_SUBRELEASE;
35383559
if (xact==target)
35393560
break;
35403561
xact=xact->parent;
@@ -3583,7 +3604,8 @@ RollbackToSavepoint(List *options)
35833604
caseTBLOCK_BEGIN:
35843605
caseTBLOCK_SUBBEGIN:
35853606
caseTBLOCK_END:
3586-
caseTBLOCK_SUBEND:
3607+
caseTBLOCK_SUBRELEASE:
3608+
caseTBLOCK_SUBCOMMIT:
35873609
caseTBLOCK_ABORT_END:
35883610
caseTBLOCK_SUBABORT_END:
35893611
caseTBLOCK_ABORT_PENDING:
@@ -3691,7 +3713,8 @@ BeginInternalSubTransaction(char *name)
36913713
caseTBLOCK_DEFAULT:
36923714
caseTBLOCK_BEGIN:
36933715
caseTBLOCK_SUBBEGIN:
3694-
caseTBLOCK_SUBEND:
3716+
caseTBLOCK_SUBRELEASE:
3717+
caseTBLOCK_SUBCOMMIT:
36953718
caseTBLOCK_ABORT:
36963719
caseTBLOCK_SUBABORT:
36973720
caseTBLOCK_ABORT_END:
@@ -3726,7 +3749,7 @@ ReleaseCurrentSubTransaction(void)
37263749
BlockStateAsString(s->blockState));
37273750
Assert(s->state==TRANS_INPROGRESS);
37283751
MemoryContextSwitchTo(CurTransactionContext);
3729-
CommitSubTransaction();
3752+
CommitSubTransaction(false);
37303753
s=CurrentTransactionState;/* changed by pop */
37313754
Assert(s->state==TRANS_INPROGRESS);
37323755
}
@@ -3757,7 +3780,8 @@ RollbackAndReleaseCurrentSubTransaction(void)
37573780
caseTBLOCK_SUBBEGIN:
37583781
caseTBLOCK_INPROGRESS:
37593782
caseTBLOCK_END:
3760-
caseTBLOCK_SUBEND:
3783+
caseTBLOCK_SUBRELEASE:
3784+
caseTBLOCK_SUBCOMMIT:
37613785
caseTBLOCK_ABORT:
37623786
caseTBLOCK_ABORT_END:
37633787
caseTBLOCK_SUBABORT_END:
@@ -3831,7 +3855,8 @@ AbortOutOfAnyTransaction(void)
38313855
*/
38323856
caseTBLOCK_SUBBEGIN:
38333857
caseTBLOCK_SUBINPROGRESS:
3834-
caseTBLOCK_SUBEND:
3858+
caseTBLOCK_SUBRELEASE:
3859+
caseTBLOCK_SUBCOMMIT:
38353860
caseTBLOCK_SUBABORT_PENDING:
38363861
caseTBLOCK_SUBRESTART:
38373862
AbortSubTransaction();
@@ -3903,7 +3928,8 @@ TransactionBlockStatusCode(void)
39033928
caseTBLOCK_INPROGRESS:
39043929
caseTBLOCK_SUBINPROGRESS:
39053930
caseTBLOCK_END:
3906-
caseTBLOCK_SUBEND:
3931+
caseTBLOCK_SUBRELEASE:
3932+
caseTBLOCK_SUBCOMMIT:
39073933
caseTBLOCK_PREPARE:
39083934
return'T';/* in transaction */
39093935
caseTBLOCK_ABORT:
@@ -3987,9 +4013,13 @@ StartSubTransaction(void)
39874013
*
39884014
*The caller has to make sure to always reassign CurrentTransactionState
39894015
*if it has a local pointer to it after calling this function.
4016+
*
4017+
*isTopLevel means that this CommitSubTransaction() is being issued as a
4018+
*sequence of actions leading directly to a main transaction commit
4019+
*allowing some actions to be optimised.
39904020
*/
39914021
staticvoid
3992-
CommitSubTransaction(void)
4022+
CommitSubTransaction(boolisTopLevel)
39934023
{
39944024
TransactionStates=CurrentTransactionState;
39954025

@@ -4036,15 +4066,21 @@ CommitSubTransaction(void)
40364066

40374067
/*
40384068
* The only lock we actually release here is the subtransaction XID lock.
4039-
* The rest just get transferred to the parent resource owner.
40404069
*/
40414070
CurrentResourceOwner=s->curTransactionOwner;
40424071
if (TransactionIdIsValid(s->transactionId))
40434072
XactLockTableDelete(s->transactionId);
40444073

4074+
/*
4075+
* Other locks should get transferred to their parent resource owner.
4076+
* Doing that is an O(N^2) operation, so if isTopLevel then we can just
4077+
* leave the lock records as they are, knowing they will all get released
4078+
* by the top level commit using ProcReleaseLocks(). We only optimize
4079+
* this for commit; aborts may need to do other cleanup.
4080+
*/
40454081
ResourceOwnerRelease(s->curTransactionOwner,
40464082
RESOURCE_RELEASE_LOCKS,
4047-
true,false);
4083+
true,isTopLevel);
40484084
ResourceOwnerRelease(s->curTransactionOwner,
40494085
RESOURCE_RELEASE_AFTER_LOCKS,
40504086
true, false);
@@ -4398,8 +4434,10 @@ BlockStateAsString(TBlockState blockState)
43984434
return"SUB BEGIN";
43994435
caseTBLOCK_SUBINPROGRESS:
44004436
return"SUB INPROGRS";
4401-
caseTBLOCK_SUBEND:
4402-
return"SUB END";
4437+
caseTBLOCK_SUBRELEASE:
4438+
return"SUB RELEASE";
4439+
caseTBLOCK_SUBCOMMIT:
4440+
return"SUB COMMIT";
44034441
caseTBLOCK_SUBABORT:
44044442
return"SUB ABORT";
44054443
caseTBLOCK_SUBABORT_END:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp