Ahh ... you know what, never mind about stack traces, let's just see if
the attached patch doesn't fix it.

I still haven't reproduced the behavior here, but I think I see what
must be happening: we are getting an sinval reset while attempting to
open pg_class_oid_index.  The latter condition causes its refcount to
be above 1, which will cause RelationClearRelation to directly call
RelationReloadIndexInfo, which enables the following sequence of calls:
RelationCacheInvalidate -> RelationClearRelation -> RelationReloadIndexInfo.
And the problem is that RelationCacheInvalidate intentionally forces
pg_class_oid_index to be updated first.  That was okay when the code was
written, because the relcache entry for pg_class itself never really
needed any updates.  Now it does, so we have to make sure pg_class gets
updated first, *then* pg_class_oid_index (which might result in a
seqscan of pg_class), then everything else (for which we'll try to use
pg_class_oid_index to locate their pg_class tuples).

                        regards, tom lane

diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 81cea8b..0e4b17c 100644
*** a/src/backend/utils/cache/relcache.c
--- b/src/backend/utils/cache/relcache.c
*************** RelationCacheInvalidate(void)
*** 2185,2204 ****
  		{
  			/*
  			 * Add this entry to list of stuff to rebuild in second pass.
! 			 * pg_class_oid_index goes on the front of rebuildFirstList, other
! 			 * nailed indexes on the back, and everything else into
! 			 * rebuildList (in no particular order).
  			 */
! 			if (relation->rd_isnailed &&
! 				relation->rd_rel->relkind == RELKIND_INDEX)
  			{
  				if (RelationGetRelid(relation) == ClassOidIndexId)
- 					rebuildFirstList = lcons(relation, rebuildFirstList);
- 				else
  					rebuildFirstList = lappend(rebuildFirstList, relation);
  			}
  			else
! 				rebuildList = lcons(relation, rebuildList);
  		}
  	}
  
--- 2185,2207 ----
  		{
  			/*
  			 * Add this entry to list of stuff to rebuild in second pass.
! 			 * pg_class goes on the front of rebuildFirstList,
! 			 * pg_class_oid_index goes to the back of rebuildFirstList, other
! 			 * nailed indexes go on the front of rebuildList, and everything
! 			 * else goes to the back of rebuildList.
  			 */
! 			if (RelationGetRelid(relation) == RelationRelationId)
! 				rebuildFirstList = lcons(relation, rebuildFirstList);
! 			else if (relation->rd_isnailed &&
! 					 relation->rd_rel->relkind == RELKIND_INDEX)
  			{
  				if (RelationGetRelid(relation) == ClassOidIndexId)
  					rebuildFirstList = lappend(rebuildFirstList, relation);
+ 				else
+ 					rebuildList = lcons(relation, rebuildList);
  			}
  			else
! 				rebuildList = lappend(rebuildList, relation);
  		}
  	}
  
-- 
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