I wrote: > it seems likely that such a cycle might be related to this new > code not properly allowing for some aspect of tuple cleanup. I found a couple places where cleanup could let these fall through the cracks long enough to get stale and still be around when a tuple ID is re-used, causing problems. Please try the attached patch and see if it fixes the problem for you. If it does, then there's no need to try to track the other things I was asking about. Thanks! -Kevin
*** 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);
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers