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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers