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