@@ -2903,9 +2903,7 @@ FastPathGetRelationLockEntry(LOCALLOCK *locallock)
2903
2903
* so use of this function has to be thought about carefully.
2904
2904
*
2905
2905
* Note we never include the current xact's vxid in the result array,
2906
- * since an xact never blocks itself. Also, prepared transactions are
2907
- * ignored, which is a bit more debatable but is appropriate for current
2908
- * uses of the result.
2906
+ * since an xact never blocks itself.
2909
2907
*/
2910
2908
VirtualTransactionId *
2911
2909
GetLockConflicts (const LOCKTAG * locktag , LOCKMODE lockmode , int * countp )
@@ -2930,19 +2928,21 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
2930
2928
2931
2929
/*
2932
2930
* Allocate memory to store results, and fill with InvalidVXID. We only
2933
- * need enough space for MaxBackends + a terminator, since prepared xacts
2934
- * don't count. InHotStandby allocate once in TopMemoryContext.
2931
+ * need enough space for MaxBackends + max_prepared_xacts + a terminator.
2932
+ * InHotStandby allocate once in TopMemoryContext.
2935
2933
*/
2936
2934
if (InHotStandby )
2937
2935
{
2938
2936
if (vxids == NULL )
2939
2937
vxids = (VirtualTransactionId * )
2940
2938
MemoryContextAlloc (TopMemoryContext ,
2941
- sizeof (VirtualTransactionId ) * (MaxBackends + 1 ));
2939
+ sizeof (VirtualTransactionId ) *
2940
+ (MaxBackends + max_prepared_xacts + 1 ));
2942
2941
}
2943
2942
else
2944
2943
vxids = (VirtualTransactionId * )
2945
- palloc0 (sizeof (VirtualTransactionId ) * (MaxBackends + 1 ));
2944
+ palloc0 (sizeof (VirtualTransactionId ) *
2945
+ (MaxBackends + max_prepared_xacts + 1 ));
2946
2946
2947
2947
/* Compute hash code and partition lock, and look up conflicting modes. */
2948
2948
hashcode = LockTagHashCode (locktag );
@@ -3017,13 +3017,9 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
3017
3017
/* Conflict! */
3018
3018
GET_VXID_FROM_PGPROC (vxid , * proc );
3019
3019
3020
- /*
3021
- * If we see an invalid VXID, then either the xact has already
3022
- * committed (or aborted), or it's a prepared xact. In either
3023
- * case we may ignore it.
3024
- */
3025
3020
if (VirtualTransactionIdIsValid (vxid ))
3026
3021
vxids [count ++ ] = vxid ;
3022
+ /* else, xact already committed or aborted */
3027
3023
3028
3024
/* No need to examine remaining slots. */
3029
3025
break ;
@@ -3082,11 +3078,6 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
3082
3078
3083
3079
GET_VXID_FROM_PGPROC (vxid , * proc );
3084
3080
3085
- /*
3086
- * If we see an invalid VXID, then either the xact has already
3087
- * committed (or aborted), or it's a prepared xact. In either
3088
- * case we may ignore it.
3089
- */
3090
3081
if (VirtualTransactionIdIsValid (vxid ))
3091
3082
{
3092
3083
int i ;
@@ -3098,6 +3089,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
3098
3089
if (i >= fast_count )
3099
3090
vxids [count ++ ] = vxid ;
3100
3091
}
3092
+ /* else, xact already committed or aborted */
3101
3093
}
3102
3094
}
3103
3095
@@ -3107,7 +3099,7 @@ GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
3107
3099
3108
3100
LWLockRelease (partitionLock );
3109
3101
3110
- if (count > MaxBackends ) /* should never happen */
3102
+ if (count > MaxBackends + max_prepared_xacts ) /* should never happen */
3111
3103
elog (PANIC , "too many conflicting locks found" );
3112
3104
3113
3105
vxids [count ].backendId = InvalidBackendId ;
@@ -4464,6 +4456,21 @@ VirtualXactLock(VirtualTransactionId vxid, bool wait)
4464
4456
4465
4457
Assert (VirtualTransactionIdIsValid (vxid ));
4466
4458
4459
+ if (VirtualTransactionIdIsPreparedXact (vxid ))
4460
+ {
4461
+ LockAcquireResult lar ;
4462
+
4463
+ /*
4464
+ * Prepared transactions don't hold vxid locks. The
4465
+ * LocalTransactionId is always a normal, locked XID.
4466
+ */
4467
+ SET_LOCKTAG_TRANSACTION (tag , vxid .localTransactionId );
4468
+ lar = LockAcquire (& tag , ShareLock , false, !wait );
4469
+ if (lar != LOCKACQUIRE_NOT_AVAIL )
4470
+ LockRelease (& tag , ShareLock , false);
4471
+ return lar != LOCKACQUIRE_NOT_AVAIL ;
4472
+ }
4473
+
4467
4474
SET_LOCKTAG_VIRTUALTRANSACTION (tag , vxid );
4468
4475
4469
4476
/*
0 commit comments