If an elog(ERROR) occurs while the reference count of a relcache entry
is positive, there is no mechanism to set the reference count back to
zero during abort cleanup.  Result: the relcache entry has a permanent
positive refcnt.

This has a number of bad effects, but one of the worst is that
RelationFlushRelation won't flush the relcache entry if called
due to an sinval update signal received during a transaction
(because RelationIdInvalidateRelationCacheByRelationId will set
onlyFlushReferenceCountZero to TRUE).  This bug can be exhibited
without even using more than one backend.  With REL6_5 sources:

regression=> create table zz (f1 int4);
CREATE
regression=> update zz set f1 = 0;
UPDATE 0
regression=> alter table zz add column f2 int4;
ADD
regression=> update zz set f2 = 0;
UPDATE 0
-- so far so good, but now trigger a deliberate error at a place where
-- f3 will be open:
regression=> update zz set f3 = 0;
ERROR:  Relation 'zz' does not have attribute 'f3'
-- now f3 has refcnt 1, so the sinval resulting from this ALTER TABLE
-- will fail to flush the relcache entry:
regression=> alter table zz add column f3 int4;
ADD
-- with the result that the backend still thinks zz has two attributes:
regression=> update zz set f3 = 0;
ERROR:  Relation 'zz' does not have attribute 'f3'
regression=> select * from zz;
f1|f2
--+--
(0 rows)


I believe that relcache.c should provide a routine (to be called during
abort cleanup) that will reset the refcnts of all relcache entries to
0 for a normal rel and 1 for a nailed-in rel.  It might be a good idea
to call this routine during normal xact commit, too, just in case
someone forgets to decrement a refcnt they've incremented.

My earlier idea of having RelationFlushRelation rebuild the cache entry
if it couldn't flush it would also mask this particular symptom.  But
that wouldn't cure the gradual relcache growth that is likely to occur
because of refcnt leakage.  I still think we probably want to do that
too, though.

Comments?  Better ideas?

			regards, tom lane

Fri, 03 Sep 1999 18:42:06 -0400
Tom Lane <tgl@sss.pgh.pa.us>
relcache.c leaks refcnts
> I believe that relcache.c should provide a routine (to be called during
> abort cleanup) that will reset the refcnts of all relcache entries to
> 0 for a normal rel and 1 for a nailed-in rel.  It might be a good idea
> to call this routine during normal xact commit, too, just in case
> someone forgets to decrement a refcnt they've incremented.
> 
> My earlier idea of having RelationFlushRelation rebuild the cache entry
> if it couldn't flush it would also mask this particular symptom.  But
> that wouldn't cure the gradual relcache growth that is likely to occur
> because of refcnt leakage.  I still think we probably want to do that
> too, though.

Yes, amazing it was this broken.  Clearing it makes sense.

-- 
  Bruce Momjian                        |  http://www.op.net/~candle
  maillist@candle.pha.pa.us            |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026

Sun, 5 Sep 1999 22:34:53 -0400 (EDT)
Bruce Momjian <maillist@candle.pha.pa.us>
Re: [HACKERS] relcache.c leaks refcnts