@@ -703,8 +703,8 @@ OldSerXidInit(void)
703703 * Set up SLRU management of the pg_serial data.
704704 */
705705 OldSerXidSlruCtl -> PagePrecedes = OldSerXidPagePrecedesLogically ;
706- SimpleLruInit (OldSerXidSlruCtl , "OldSerXid SLRU Ctl" , NUM_OLDSERXID_BUFFERS , 0 ,
707- OldSerXidLock , "pg_serial" );
706+ SimpleLruInit (OldSerXidSlruCtl , "OldSerXid SLRU Ctl" ,
707+ NUM_OLDSERXID_BUFFERS , 0 , OldSerXidLock , "pg_serial" );
708708 /* Override default assumption that writes should be fsync'd */
709709 OldSerXidSlruCtl -> do_fsync = false;
710710
@@ -2954,7 +2954,8 @@ PredicateLockPageCombine(const Relation relation, const BlockNumber oldblkno,
29542954}
29552955
29562956/*
2957- * Walk the hash table and find the new xmin.
2957+ * Walk the list of in-progress serializable transactions and find the new
2958+ * xmin.
29582959 */
29592960static void
29602961SetNewSxactGlobalXmin (void )
@@ -3126,6 +3127,10 @@ ReleasePredicateLocks(const bool isCommit)
31263127 && !SxactIsReadOnly (MySerializableXact )
31273128 && SxactHasSummaryConflictOut (MySerializableXact ))
31283129 {
3130+ /*
3131+ * we don't know which old committed transaction we conflicted with,
3132+ * so be conservative and use FirstNormalSerCommitSeqNo here
3133+ */
31293134 MySerializableXact -> SeqNo .earliestOutConflictCommit =
31303135 FirstNormalSerCommitSeqNo ;
31313136 MySerializableXact -> flags |= SXACT_FLAG_CONFLICT_OUT ;
@@ -3320,14 +3325,19 @@ ReleasePredicateLocksIfROSafe(void)
33203325}
33213326
33223327/*
3323- * Clear old predicate locks.
3328+ * Clear old predicate locks, belonging to committed transactions that are no
3329+ * longer interesting to any in-progress transaction.
33243330 */
33253331static void
33263332ClearOldPredicateLocks (void )
33273333{
33283334 SERIALIZABLEXACT * finishedSxact ;
33293335 PREDICATELOCK * predlock ;
33303336
3337+ /*
3338+ * Loop through finished transactions. They are in commit order, so we can
3339+ * stop as soon as we find one that's still interesting.
3340+ */
33313341 LWLockAcquire (SerializableFinishedListLock , LW_EXCLUSIVE );
33323342 finishedSxact = (SERIALIZABLEXACT * )
33333343 SHMQueueNext (FinishedSerializableTransactions ,
@@ -3346,6 +3356,10 @@ ClearOldPredicateLocks(void)
33463356 || TransactionIdPrecedesOrEquals (finishedSxact -> finishedBefore ,
33473357 PredXact -> SxactGlobalXmin ))
33483358 {
3359+ /*
3360+ * This transaction committed before any in-progress transaction
3361+ * took its snapshot. It's no longer interesting.
3362+ */
33493363 LWLockRelease (SerializableXactHashLock );
33503364 SHMQueueDelete (& (finishedSxact -> finishedLink ));
33513365 ReleaseOneSerializableXact (finishedSxact , false, false);
@@ -3362,7 +3376,10 @@ ClearOldPredicateLocks(void)
33623376 LWLockAcquire (SerializableXactHashLock , LW_SHARED );
33633377 }
33643378 else
3379+ {
3380+ /* Still interesting. */
33653381 break ;
3382+ }
33663383 finishedSxact = nextSxact ;
33673384 }
33683385 LWLockRelease (SerializableXactHashLock );
@@ -3391,25 +3408,27 @@ ClearOldPredicateLocks(void)
33913408 canDoPartialCleanup = (predlock -> commitSeqNo <= PredXact -> CanPartialClearThrough );
33923409 LWLockRelease (SerializableXactHashLock );
33933410
3411+ /*
3412+ * If this lock originally belonged to an old enough transaction, we
3413+ * can release it.
3414+ */
33943415 if (canDoPartialCleanup )
33953416 {
33963417 PREDICATELOCKTAG tag ;
3397- SHM_QUEUE * targetLink ;
33983418 PREDICATELOCKTARGET * target ;
33993419 PREDICATELOCKTARGETTAG targettag ;
34003420 uint32 targettaghash ;
34013421 LWLockId partitionLock ;
34023422
34033423 tag = predlock -> tag ;
3404- targetLink = & (predlock -> targetLink );
34053424 target = tag .myTarget ;
34063425 targettag = target -> tag ;
34073426 targettaghash = PredicateLockTargetTagHashCode (& targettag );
34083427 partitionLock = PredicateLockHashPartitionLock (targettaghash );
34093428
34103429 LWLockAcquire (partitionLock , LW_EXCLUSIVE );
34113430
3412- SHMQueueDelete (targetLink );
3431+ SHMQueueDelete (& ( predlock -> targetLink ) );
34133432 SHMQueueDelete (& (predlock -> xactLink ));
34143433
34153434 hash_search_with_hash_value (PredicateLockHash , & tag ,
@@ -3437,9 +3456,9 @@ ClearOldPredicateLocks(void)
34373456 * delete the transaction.
34383457 *
34393458 * When the partial flag is set, we can release all predicate locks and
3440- * out -conflict information -- we've established that there are no longer
3459+ * in -conflict information -- we've established that there are no longer
34413460 * any overlapping read write transactions for which this transaction could
3442- * matter.
3461+ * matter -- but keep the transaction entry itself and any outConflicts .
34433462 *
34443463 * When the summarize flag is set, we've run short of room for sxact data
34453464 * and must summarize to the SLRU. Predicate locks are transferred to a
@@ -3460,6 +3479,10 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
34603479 Assert (SxactIsRolledBack (sxact ) || SxactIsCommitted (sxact ));
34613480 Assert (LWLockHeldByMe (SerializableFinishedListLock ));
34623481
3482+ /*
3483+ * First release all the predicate locks held by this xact (or transfer
3484+ * them to OldCommittedSxact if summarize is true)
3485+ */
34633486 LWLockAcquire (SerializablePredicateLockListLock , LW_SHARED );
34643487 predlock = (PREDICATELOCK * )
34653488 SHMQueueNext (& (sxact -> predicateLocks ),
@@ -3545,9 +3568,9 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
35453568 sxidtag .xid = sxact -> topXid ;
35463569 LWLockAcquire (SerializableXactHashLock , LW_EXCLUSIVE );
35473570
3571+ /* Release all outConflicts (unless 'partial' is true) */
35483572 if (!partial )
35493573 {
3550- /* Release all outConflicts. */
35513574 conflict = (RWConflict )
35523575 SHMQueueNext (& sxact -> outConflicts ,
35533576 & sxact -> outConflicts ,
@@ -3582,9 +3605,9 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
35823605 conflict = nextConflict ;
35833606 }
35843607
3608+ /* Finally, get rid of the xid and the record of the transaction itself. */
35853609 if (!partial )
35863610 {
3587- /* Get rid of the xid and the record of the transaction itself. */
35883611 if (sxidtag .xid != InvalidTransactionId )
35893612 hash_search (SerializableXidHash , & sxidtag , HASH_REMOVE , NULL );
35903613 ReleasePredXact (sxact );
@@ -3844,7 +3867,8 @@ CheckForSerializableConflictOut(const bool visible, const Relation relation,
38443867}
38453868
38463869/*
3847- * Check a particular target for rw-dependency conflict in.
3870+ * Check a particular target for rw-dependency conflict in. A subroutine of
3871+ * CheckForSerializableConflictIn().
38483872 */
38493873static void
38503874CheckTargetForConflictsIn (PREDICATELOCKTARGETTAG * targettag )
0 commit comments