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

Commitdb10834

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 parent5ebaaa4 commitdb10834

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
@@ -108,8 +108,8 @@ intmax_prepared_xacts = 0;
108108

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

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

306309
proc=&ProcGlobal->allProcs[gxact->pgprocno];
307310
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