@@ -2275,6 +2275,18 @@ PredicateLockTupleRowVersionLink(const Relation relation,
22752275TransactionId oldxmin ,
22762276newxmin ;
22772277
2278+ /*
2279+ * Bail out quickly if there are no serializable transactions
2280+ * running.
2281+ *
2282+ * It's safe to do this check without taking any additional
2283+ * locks. Even if a serializable transaction starts concurrently,
2284+ * we know it can't take any SIREAD locks on the modified tuple
2285+ * because the caller is holding the associated buffer page lock.
2286+ */
2287+ if (!TransactionIdIsValid (PredXact -> SxactGlobalXmin ))
2288+ return ;
2289+
22782290oldblk = ItemPointerGetBlockNumber (& (oldTuple -> t_self ));
22792291oldoff = ItemPointerGetOffsetNumber (& (oldTuple -> t_self ));
22802292oldxmin = HeapTupleHeaderGetXmin (oldTuple -> t_data );
@@ -2633,6 +2645,15 @@ PredicateLockPageSplit(const Relation relation, const BlockNumber oldblkno,
26332645PREDICATELOCKTARGETTAG newtargettag ;
26342646bool success ;
26352647
2648+ /*
2649+ * Bail out quickly if there are no serializable transactions
2650+ * running. As with PredicateLockTupleRowVersionLink, it's safe to
2651+ * check this without taking locks because the caller is holding
2652+ * the buffer page lock.
2653+ */
2654+ if (!TransactionIdIsValid (PredXact -> SxactGlobalXmin ))
2655+ return ;
2656+
26362657if (SkipSplitTracking (relation ))
26372658return ;
26382659