@@ -107,8 +107,8 @@ int max_prepared_xacts = 0;
107
107
108
108
typedef struct GlobalTransactionData
109
109
{
110
- GlobalTransaction next ;
111
- int pgprocno ; /* dummy proc */
110
+ GlobalTransaction next ; /* list link for free list */
111
+ int pgprocno ; /* ID of associated dummy PGPROC */
112
112
BackendId dummyBackendId ; /* similar to backend id for backends */
113
113
TimestampTz prepared_at ; /* time of preparation */
114
114
XLogRecPtr prepare_lsn ; /* XLOG offset of prepare record */
@@ -202,10 +202,13 @@ TwoPhaseShmemInit(void)
202
202
sizeof (GlobalTransaction ) * max_prepared_xacts ));
203
203
for (i = 0 ; i < max_prepared_xacts ; i ++ )
204
204
{
205
- gxacts [ i ]. pgprocno = PreparedXactProcs [ i ]. pgprocno ;
205
+ /* insert into linked list */
206
206
gxacts [i ].next = TwoPhaseState -> freeGXacts ;
207
207
TwoPhaseState -> freeGXacts = & gxacts [i ];
208
208
209
+ /* associate it with a PGPROC assigned by InitProcGlobal */
210
+ gxacts [i ].pgprocno = PreparedXactProcs [i ].pgprocno ;
211
+
209
212
/*
210
213
* Assign a unique ID for each dummy proc, so that the range of
211
214
* dummy backend IDs immediately follows the range of normal
@@ -300,7 +303,7 @@ MarkAsPreparing(TransactionId xid, const char *gid,
300
303
errhint ("Increase max_prepared_transactions (currently %d)." ,
301
304
max_prepared_xacts )));
302
305
gxact = TwoPhaseState -> freeGXacts ;
303
- TwoPhaseState -> freeGXacts = ( GlobalTransaction ) gxact -> next ;
306
+ TwoPhaseState -> freeGXacts = gxact -> next ;
304
307
305
308
proc = & ProcGlobal -> allProcs [gxact -> pgprocno ];
306
309
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