*** a/src/backend/storage/lmgr/predicate.c --- b/src/backend/storage/lmgr/predicate.c *************** *** 2329,2334 **** PredicateLockTupleRowVersionLink(const Relation relation, --- 2329,2336 ---- if (next != NULL) { next->priorVersionOfRow = NULL; + if (SHMQueueEmpty(&next->predicateLocks)) + PredXact->NeedTargetLinkCleanup = true; oldtarget->nextVersionOfRow = NULL; } *************** *** 3128,3133 **** ClearOldPredicateLocks(void) --- 3130,3136 ---- int i; HASH_SEQ_STATUS seqstat; PREDICATELOCKTARGET *locktarget; + PREDICATELOCKTARGET *next; LWLockAcquire(SerializableFinishedListLock, LW_EXCLUSIVE); finishedSxact = (SERIALIZABLEXACT *) *************** *** 3237,3256 **** ClearOldPredicateLocks(void) LWLockAcquire(FirstPredicateLockMgrLock + i, LW_EXCLUSIVE); LWLockAcquire(PredicateLockNextRowLinkLock, LW_SHARED); ! hash_seq_init(&seqstat, PredicateLockTargetHash); ! while ((locktarget = (PREDICATELOCKTARGET *) hash_seq_search(&seqstat))) { ! if (SHMQueueEmpty(&locktarget->predicateLocks) ! && locktarget->priorVersionOfRow == NULL ! && locktarget->nextVersionOfRow == NULL) { ! hash_search(PredicateLockTargetHash, &locktarget->tag, ! HASH_REMOVE, NULL); } } - PredXact->NeedTargetLinkCleanup = false; - LWLockRelease(PredicateLockNextRowLinkLock); for (i = NUM_PREDICATELOCK_PARTITIONS - 1; i >= 0; i--) LWLockRelease(FirstPredicateLockMgrLock + i); --- 3240,3267 ---- LWLockAcquire(FirstPredicateLockMgrLock + i, LW_EXCLUSIVE); LWLockAcquire(PredicateLockNextRowLinkLock, LW_SHARED); ! while (PredXact->NeedTargetLinkCleanup) { ! PredXact->NeedTargetLinkCleanup = false; ! hash_seq_init(&seqstat, PredicateLockTargetHash); ! while ((locktarget = (PREDICATELOCKTARGET *) hash_seq_search(&seqstat))) { ! if (SHMQueueEmpty(&locktarget->predicateLocks) ! && locktarget->priorVersionOfRow == NULL) ! { ! next = locktarget->nextVersionOfRow; ! if (next != NULL) ! { ! next->priorVersionOfRow = NULL; ! if (SHMQueueEmpty(&next->predicateLocks)) ! PredXact->NeedTargetLinkCleanup = true; ! } ! hash_search(PredicateLockTargetHash, &locktarget->tag, ! HASH_REMOVE, NULL); ! } } } LWLockRelease(PredicateLockNextRowLinkLock); for (i = NUM_PREDICATELOCK_PARTITIONS - 1; i >= 0; i--) LWLockRelease(FirstPredicateLockMgrLock + i);