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

Reply via email to