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

Commit5cf2307

Browse files
committed
Fix TwoPhaseGetDummyBackendId().
This was broken in commited0b409,which revised the GlobalTransactionData struct to not include theassociated PGPROC as its first member, but overlooked one place wherea cast was used in reliance on that equivalence.The most effective way of fixing this seems to be to create a new functionthat looks up the GlobalTransactionData struct given the XID, and makeboth TwoPhaseGetDummyBackendId and TwoPhaseGetDummyProc rely on that.Per report from Robert Ross.
1 parent7d947ec commit5cf2307

File tree

1 file changed

+46
-30
lines changed

1 file changed

+46
-30
lines changed

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

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ intmax_prepared_xacts = 0;
107107

108108
typedefstructGlobalTransactionData
109109
{
110-
GlobalTransactionnext;
111-
intpgprocno;/* dummyproc */
110+
GlobalTransactionnext;/* list link for free list */
111+
intpgprocno;/*ID of associateddummyPGPROC */
112112
BackendIddummyBackendId;/* similar to backend id for backends */
113113
TimestampTzprepared_at;/* time of preparation */
114114
XLogRecPtrprepare_lsn;/* XLOG offset of prepare record */
@@ -202,10 +202,13 @@ TwoPhaseShmemInit(void)
202202
sizeof(GlobalTransaction)*max_prepared_xacts));
203203
for (i=0;i<max_prepared_xacts;i++)
204204
{
205-
gxacts[i].pgprocno=PreparedXactProcs[i].pgprocno;
205+
/* insert into linked list */
206206
gxacts[i].next=TwoPhaseState->freeGXacts;
207207
TwoPhaseState->freeGXacts=&gxacts[i];
208208

209+
/* associate it with a PGPROC assigned by InitProcGlobal */
210+
gxacts[i].pgprocno=PreparedXactProcs[i].pgprocno;
211+
209212
/*
210213
* Assign a unique ID for each dummy proc, so that the range of
211214
* dummy backend IDs immediately follows the range of normal
@@ -300,7 +303,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
300303
errhint("Increase max_prepared_transactions (currently %d).",
301304
max_prepared_xacts)));
302305
gxact=TwoPhaseState->freeGXacts;
303-
TwoPhaseState->freeGXacts=(GlobalTransaction)gxact->next;
306+
TwoPhaseState->freeGXacts=gxact->next;
304307

305308
proc=&ProcGlobal->allProcs[gxact->pgprocno];
306309
pgxact=&ProcGlobal->allPgXact[gxact->pgprocno];
@@ -680,40 +683,25 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
680683
}
681684

682685
/*
683-
* TwoPhaseGetDummyProc
684-
*Get the dummy backend ID for prepared transaction specified by XID
685-
*
686-
* Dummy backend IDs are similar to real backend IDs of real backends.
687-
* They start at MaxBackends + 1, and are unique across all currently active
688-
* real backends and prepared transactions.
686+
* TwoPhaseGetGXact
687+
*Get the GlobalTransaction struct for a prepared transaction
688+
*specified by XID
689689
*/
690-
BackendId
691-
TwoPhaseGetDummyBackendId(TransactionIdxid)
692-
{
693-
PGPROC*proc=TwoPhaseGetDummyProc(xid);
694-
695-
return ((GlobalTransaction)proc)->dummyBackendId;
696-
}
697-
698-
/*
699-
* TwoPhaseGetDummyProc
700-
*Get the PGPROC that represents a prepared transaction specified by XID
701-
*/
702-
PGPROC*
703-
TwoPhaseGetDummyProc(TransactionIdxid)
690+
staticGlobalTransaction
691+
TwoPhaseGetGXact(TransactionIdxid)
704692
{
705-
PGPROC*result=NULL;
693+
GlobalTransactionresult=NULL;
706694
inti;
707695

708696
staticTransactionIdcached_xid=InvalidTransactionId;
709-
staticPGPROC*cached_proc=NULL;
697+
staticGlobalTransactioncached_gxact=NULL;
710698

711699
/*
712700
* During a recovery, COMMIT PREPARED, or ABORT PREPARED, we'll be called
713701
* repeatedly for the same XID. We can save work with a simple cache.
714702
*/
715703
if (xid==cached_xid)
716-
returncached_proc;
704+
returncached_gxact;
717705

718706
LWLockAcquire(TwoPhaseStateLock,LW_SHARED);
719707

@@ -724,22 +712,50 @@ TwoPhaseGetDummyProc(TransactionId xid)
724712

725713
if (pgxact->xid==xid)
726714
{
727-
result=&ProcGlobal->allProcs[gxact->pgprocno];
715+
result=gxact;
728716
break;
729717
}
730718
}
731719

732720
LWLockRelease(TwoPhaseStateLock);
733721

734722
if (result==NULL)/* should not happen */
735-
elog(ERROR,"failed to finddummy PGPROC for xid %u",xid);
723+
elog(ERROR,"failed to findGlobalTransaction for xid %u",xid);
736724

737725
cached_xid=xid;
738-
cached_proc=result;
726+
cached_gxact=result;
739727

740728
returnresult;
741729
}
742730

731+
/*
732+
* TwoPhaseGetDummyProc
733+
*Get the dummy backend ID for prepared transaction specified by XID
734+
*
735+
* Dummy backend IDs are similar to real backend IDs of real backends.
736+
* They start at MaxBackends + 1, and are unique across all currently active
737+
* real backends and prepared transactions.
738+
*/
739+
BackendId
740+
TwoPhaseGetDummyBackendId(TransactionIdxid)
741+
{
742+
GlobalTransactiongxact=TwoPhaseGetGXact(xid);
743+
744+
returngxact->dummyBackendId;
745+
}
746+
747+
/*
748+
* TwoPhaseGetDummyProc
749+
*Get the PGPROC that represents a prepared transaction specified by XID
750+
*/
751+
PGPROC*
752+
TwoPhaseGetDummyProc(TransactionIdxid)
753+
{
754+
GlobalTransactiongxact=TwoPhaseGetGXact(xid);
755+
756+
return&ProcGlobal->allProcs[gxact->pgprocno];
757+
}
758+
743759
/************************************************************************/
744760
/* State file support*/
745761
/************************************************************************/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp