@@ -2788,9 +2788,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
2788
2788
* so use of this function has to be thought about carefully.
2789
2789
*
2790
2790
* Note we never include the current xact's vxid in the result array,
2791
- * since an xact never blocks itself. Also, prepared transactions are
2792
- * ignored, which is a bit more debatable but is appropriate for current
2793
- * uses of the result.
2791
+ * since an xact never blocks itself.
2794
2792
*/
2795
2793
VirtualTransactionId *
2796
2794
GetLockConflicts (const LOCKTAG * locktag , LOCKMODE lockmode )
@@ -2815,19 +2813,21 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
2815
2813
2816
2814
/*
2817
2815
* Allocate memory to store results, and fill with InvalidVXID. We only
2818
- * need enough space for MaxBackends + a terminator, since prepared xacts
2819
- * don't count. InHotStandby allocate once in TopMemoryContext.
2816
+ * need enough space for MaxBackends + max_prepared_xacts + a terminator.
2817
+ * InHotStandby allocate once in TopMemoryContext.
2820
2818
*/
2821
2819
if (InHotStandby )
2822
2820
{
2823
2821
if (vxids == NULL )
2824
2822
vxids = (VirtualTransactionId * )
2825
2823
MemoryContextAlloc (TopMemoryContext ,
2826
- sizeof (VirtualTransactionId ) * (MaxBackends + 1 ));
2824
+ sizeof (VirtualTransactionId ) *
2825
+ (MaxBackends + max_prepared_xacts + 1 ));
2827
2826
}
2828
2827
else
2829
2828
vxids = (VirtualTransactionId * )
2830
- palloc0 (sizeof (VirtualTransactionId ) * (MaxBackends + 1 ));
2829
+ palloc0 (sizeof (VirtualTransactionId ) *
2830
+ (MaxBackends + max_prepared_xacts + 1 ));
2831
2831
2832
2832
/* Compute hash code and partition lock, and look up conflicting modes. */
2833
2833
hashcode = LockTagHashCode (locktag );
@@ -2902,13 +2902,9 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
2902
2902
/* Conflict! */
2903
2903
GET_VXID_FROM_PGPROC (vxid , * proc );
2904
2904
2905
- /*
2906
- * If we see an invalid VXID, then either the xact has already
2907
- * committed (or aborted), or it's a prepared xact. In either
2908
- * case we may ignore it.
2909
- */
2910
2905
if (VirtualTransactionIdIsValid (vxid ))
2911
2906
vxids [count ++ ] = vxid ;
2907
+ /* else, xact already committed or aborted */
2912
2908
2913
2909
/* No need to examine remaining slots. */
2914
2910
break ;
@@ -2965,11 +2961,6 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
2965
2961
2966
2962
GET_VXID_FROM_PGPROC (vxid , * proc );
2967
2963
2968
- /*
2969
- * If we see an invalid VXID, then either the xact has already
2970
- * committed (or aborted), or it's a prepared xact. In either
2971
- * case we may ignore it.
2972
- */
2973
2964
if (VirtualTransactionIdIsValid (vxid ))
2974
2965
{
2975
2966
int i ;
@@ -2981,6 +2972,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
2981
2972
if (i >= fast_count )
2982
2973
vxids [count ++ ] = vxid ;
2983
2974
}
2975
+ /* else, xact already committed or aborted */
2984
2976
}
2985
2977
}
2986
2978
@@ -2990,7 +2982,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
2990
2982
2991
2983
LWLockRelease (partitionLock );
2992
2984
2993
- if (count > MaxBackends ) /* should never happen */
2985
+ if (count > MaxBackends + max_prepared_xacts ) /* should never happen */
2994
2986
elog (PANIC , "too many conflicting locks found" );
2995
2987
2996
2988
vxids [count ].backendId = InvalidBackendId ;
@@ -4346,6 +4338,21 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait)
4346
4338
4347
4339
Assert (VirtualTransactionIdIsValid (vxid ));
4348
4340
4341
+ if (VirtualTransactionIdIsPreparedXact (vxid ))
4342
+ {
4343
+ LockAcquireResult lar ;
4344
+
4345
+ /*
4346
+ * Prepared transactions don't hold vxid locks. The
4347
+ * LocalTransactionId is always a normal, locked XID.
4348
+ */
4349
+ SET_LOCKTAG_TRANSACTION (tag , vxid .localTransactionId );
4350
+ lar = LockAcquire (& tag , ShareLock , false, !wait );
4351
+ if (lar != LOCKACQUIRE_NOT_AVAIL )
4352
+ LockRelease (& tag , ShareLock , false);
4353
+ return lar != LOCKACQUIRE_NOT_AVAIL ;
4354
+ }
4355
+
4349
4356
SET_LOCKTAG_VIRTUALTRANSACTION (tag , vxid );
4350
4357
4351
4358
/*
0 commit comments