@@ -150,7 +150,7 @@ typedef struct GlobalTransactionData
150
150
XLogRecPtr prepare_end_lsn ; /* XLOG offset of prepare record end */
151
151
152
152
Oid owner ; /* ID of user that executed the xact */
153
- BackendId locking_backend ; /* backend currently working on the xact */
153
+ int locking_pid ; /* backend currently working on the xact */
154
154
bool valid ; /* TRUE if PGPROC entry is in proc array */
155
155
bool ondisk ; /* TRUE if prepare state file is on disk */
156
156
int prep_index ; /* Index of prepXacts array */
@@ -358,6 +358,7 @@ TwoPhaseShmemInit(void)
358
358
*/
359
359
gxacts [i ].dummyBackendId = MaxBackends + 1 + i ;
360
360
SpinLockInit (& gxacts [i ].spinlock );
361
+ gxacts [i ].locking_pid = -1 ;
361
362
}
362
363
}
363
364
else
@@ -382,7 +383,7 @@ AtAbort_Twophase(void)
382
383
{
383
384
if (MyLockedGxact == NULL )
384
385
return ;
385
-
386
+ Assert ( MyLockedGxact -> locking_pid >= 0 );
386
387
/*
387
388
* What to do with the locked global transaction entry? If we were in the
388
389
* process of preparing the transaction, but haven't written the WAL
@@ -409,7 +410,7 @@ AtAbort_Twophase(void)
409
410
}
410
411
else
411
412
{
412
- MyLockedGxact -> locking_backend = InvalidBackendId ;
413
+ MyLockedGxact -> locking_pid = -1 ;
413
414
SpinLockRelease (& MyLockedGxact -> spinlock );
414
415
}
415
416
MyLockedGxact = NULL ;
@@ -422,8 +423,8 @@ AtAbort_Twophase(void)
422
423
void
423
424
PostPrepare_Twophase (void )
424
425
{
425
- Assert (MyLockedGxact -> locking_backend != InvalidBackendId );
426
- MyLockedGxact -> locking_backend = InvalidBackendId ;
426
+ Assert (MyLockedGxact -> locking_pid >= 0 );
427
+ MyLockedGxact -> locking_pid = -1 ;
427
428
SpinLockRelease (& MyLockedGxact -> spinlock );
428
429
MyLockedGxact = NULL ;
429
430
}
@@ -496,6 +497,8 @@ MarkAsPreparing(TransactionId xid, const char *gid,
496
497
SpinLockAcquire (& gxact -> spinlock );
497
498
LWLockAcquire (TwoPhaseStateLock , LW_EXCLUSIVE );
498
499
500
+ Assert (gxact -> locking_pid < 0 );
501
+
499
502
/* Include in collision chain */
500
503
gxact -> next = TwoPhaseState -> hashTable [i ];
501
504
TwoPhaseState -> hashTable [i ] = gxact ;
@@ -537,9 +540,9 @@ MarkAsPreparing(TransactionId xid, const char *gid,
537
540
gxact -> prepare_start_lsn = InvalidXLogRecPtr ;
538
541
gxact -> prepare_end_lsn = InvalidXLogRecPtr ;
539
542
gxact -> owner = owner ;
540
- gxact -> locking_backend = MyBackendId ;
543
+ gxact -> locking_pid = MyProcPid ;
541
544
gxact -> valid = false;
542
- gxact -> ondisk = false;
545
+ gxact -> ondisk = false;
543
546
gxact -> prep_index = TwoPhaseState -> numPrepXacts ;
544
547
strcpy (gxact -> gid , gid );
545
548
* gxact -> state_3pc = '\0' ;
@@ -646,14 +649,6 @@ LockGXact(const char *gid, Oid user)
646
649
errmsg ("prepared transaction with identifier \"%s\" is not valid" ,
647
650
gid )));
648
651
}
649
- /* Found it, but has someone else got it locked? */
650
- if (gxact -> locking_backend != InvalidBackendId ) {
651
- SpinLockRelease (& gxact -> spinlock );
652
- ereport (ERROR ,
653
- (errcode (ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE ),
654
- errmsg ("prepared transaction with identifier \"%s\" is busy" ,
655
- gid )));
656
- }
657
652
658
653
if (user != gxact -> owner && !superuser_arg (user )) {
659
654
SpinLockRelease (& gxact -> spinlock );
@@ -679,7 +674,8 @@ LockGXact(const char *gid, Oid user)
679
674
680
675
681
676
/* OK for me to lock it */
682
- gxact -> locking_backend = MyBackendId ;
677
+ Assert (gxact -> locking_pid < 0 );
678
+ gxact -> locking_pid = MyProcPid ;
683
679
MyLockedGxact = gxact ;
684
680
685
681
return gxact ;
@@ -729,6 +725,8 @@ RemoveGXact(GlobalTransaction gxact)
729
725
gxact -> next = TwoPhaseState -> freeGXacts ;
730
726
TwoPhaseState -> freeGXacts = gxact ;
731
727
728
+ gxact -> locking_pid = -1 ;
729
+
732
730
LWLockRelease (TwoPhaseStateLock );
733
731
SpinLockRelease (& gxact -> spinlock );
734
732
0 commit comments