@@ -108,8 +108,8 @@ int max_prepared_xacts = 0;
108
108
109
109
typedef struct GlobalTransactionData
110
110
{
111
- GlobalTransaction next ;
112
- int pgprocno ; /* dummy proc */
111
+ GlobalTransaction next ; /* list link for free list */
112
+ int pgprocno ; /* ID of associated dummy PGPROC */
113
113
BackendId dummyBackendId ; /* similar to backend id for backends */
114
114
TimestampTz prepared_at ; /* time of preparation */
115
115
XLogRecPtr prepare_lsn ; /* XLOG offset of prepare record */
@@ -203,10 +203,13 @@ TwoPhaseShmemInit(void)
203
203
sizeof (GlobalTransaction ) * max_prepared_xacts ));
204
204
for (i = 0 ; i < max_prepared_xacts ; i ++ )
205
205
{
206
- gxacts [ i ]. pgprocno = PreparedXactProcs [ i ]. pgprocno ;
206
+ /* insert into linked list */
207
207
gxacts [i ].next = TwoPhaseState -> freeGXacts ;
208
208
TwoPhaseState -> freeGXacts = & gxacts [i ];
209
209
210
+ /* associate it with a PGPROC assigned by InitProcGlobal */
211
+ gxacts [i ].pgprocno = PreparedXactProcs [i ].pgprocno ;
212
+
210
213
/*
211
214
* Assign a unique ID for each dummy proc, so that the range of
212
215
* dummy backend IDs immediately follows the range of normal
@@ -301,7 +304,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
301
304
errhint ("Increase max_prepared_transactions (currently %d)." ,
302
305
max_prepared_xacts )));
303
306
gxact = TwoPhaseState -> freeGXacts ;
304
- TwoPhaseState -> freeGXacts = ( GlobalTransaction ) gxact -> next ;
307
+ TwoPhaseState -> freeGXacts = gxact -> next ;
305
308
306
309
proc = & ProcGlobal -> allProcs [gxact -> pgprocno ];
307
310
pgxact = & ProcGlobal -> allPgXact [gxact -> pgprocno ];
@@ -680,40 +683,25 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
680
683
}
681
684
682
685
/*
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
689
689
*/
690
- BackendId
691
- TwoPhaseGetDummyBackendId (TransactionId xid )
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 (TransactionId xid )
690
+ static GlobalTransaction
691
+ TwoPhaseGetGXact (TransactionId xid )
704
692
{
705
- PGPROC * result = NULL ;
693
+ GlobalTransaction result = NULL ;
706
694
int i ;
707
695
708
696
static TransactionId cached_xid = InvalidTransactionId ;
709
- static PGPROC * cached_proc = NULL ;
697
+ static GlobalTransaction cached_gxact = NULL ;
710
698
711
699
/*
712
700
* During a recovery, COMMIT PREPARED, or ABORT PREPARED, we'll be called
713
701
* repeatedly for the same XID. We can save work with a simple cache.
714
702
*/
715
703
if (xid == cached_xid )
716
- return cached_proc ;
704
+ return cached_gxact ;
717
705
718
706
LWLockAcquire (TwoPhaseStateLock , LW_SHARED );
719
707
@@ -724,22 +712,50 @@ TwoPhaseGetDummyProc(TransactionId xid)
724
712
725
713
if (pgxact -> xid == xid )
726
714
{
727
- result = & ProcGlobal -> allProcs [ gxact -> pgprocno ] ;
715
+ result = gxact ;
728
716
break ;
729
717
}
730
718
}
731
719
732
720
LWLockRelease (TwoPhaseStateLock );
733
721
734
722
if (result == NULL ) /* should not happen */
735
- elog (ERROR , "failed to find dummy PGPROC for xid %u" , xid );
723
+ elog (ERROR , "failed to find GlobalTransaction for xid %u" , xid );
736
724
737
725
cached_xid = xid ;
738
- cached_proc = result ;
726
+ cached_gxact = result ;
739
727
740
728
return result ;
741
729
}
742
730
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 (TransactionId xid )
741
+ {
742
+ GlobalTransaction gxact = TwoPhaseGetGXact (xid );
743
+
744
+ return gxact -> dummyBackendId ;
745
+ }
746
+
747
+ /*
748
+ * TwoPhaseGetDummyProc
749
+ * Get the PGPROC that represents a prepared transaction specified by XID
750
+ */
751
+ PGPROC *
752
+ TwoPhaseGetDummyProc (TransactionId xid )
753
+ {
754
+ GlobalTransaction gxact = TwoPhaseGetGXact (xid );
755
+
756
+ return & ProcGlobal -> allProcs [gxact -> pgprocno ];
757
+ }
758
+
743
759
/************************************************************************/
744
760
/* State file support */
745
761
/************************************************************************/
0 commit comments