Re: REINDEX INDEX results in a crash for an index of pg_class since 9.6

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: Michael Paquier <michael@paquier.xyz>
Cc: Postgres hackers <pgsql-hackers@lists.postgresql.org>
Date: 2019-04-23T23:54:52Z
Lists: pgsql-hackers
Michael Paquier <michael@paquier.xyz> writes:
> On Tue, Apr 23, 2019 at 04:47:19PM -0400, Tom Lane wrote:
>> Is there some precondition you're not mentioning?

> Hm.  In my own init scripts, I create a new database just after
> starting the instance.

Ah, there we go:

regression=# create database d1;
CREATE DATABASE
regression=# \c d1
You are now connected to database "d1" as user "postgres".
d1=# reindex index pg_class_relname_nsp_index;
psql: server closed the connection unexpectedly

log shows

TRAP: FailedAssertion("!(!ReindexIsProcessingIndex(((indexRelation)->rd_id)))", File: "indexam.c", Line: 204)

#2  0x00000000008c74ed in ExceptionalCondition (
    conditionName=<value optimized out>, errorType=<value optimized out>, 
    fileName=<value optimized out>, lineNumber=<value optimized out>)
    at assert.c:54
#3  0x00000000004e4f8c in index_insert (indexRelation=0x7f80f849a5d8, 
    values=0x7ffc4f65b030, isnull=0x7ffc4f65b130, heap_t_ctid=0x2842c0c, 
    heapRelation=0x7f80f84bab68, checkUnique=UNIQUE_CHECK_YES, 
    indexInfo=0x2843230) at indexam.c:204
#4  0x000000000054c290 in CatalogIndexInsert (indstate=<value optimized out>, 
    heapTuple=0x2842c08) at indexing.c:140
#5  0x000000000054c472 in CatalogTupleUpdate (heapRel=0x7f80f84bab68, 
    otid=0x2842c0c, tup=0x2842c08) at indexing.c:215
#6  0x00000000008bca77 in RelationSetNewRelfilenode (relation=0x7f80f849a5d8, 
    persistence=112 'p') at relcache.c:3531
#7  0x0000000000548b3a in reindex_index (indexId=2663, 
    skip_constraint_checks=false, persistence=112 'p', options=0)
    at index.c:3339
#8  0x00000000005ed099 in ReindexIndex (indexRelation=<value optimized out>, 
    options=0, concurrent=false) at indexcmds.c:2304
#9  0x00000000007b5925 in standard_ProcessUtility (pstmt=0x281fd70, 

> If I apply my previous patch to make CatalogIndexInsert() not do
> an insert on a catalog index being rebuilt, then things turn to be
> fine.

That seems like pretty much of a hack :-(, in particular I'm not
convinced that we'd not end up with a missing index entry afterwards.
Maybe it's the only way, but I think first we need to trace down
exactly why this broke.  I remember we had some special-case code
for reindexing pg_class, maybe something broke that?

It also seems quite odd that it doesn't fail every time; surely it's
not conditional whether we'll try to insert a new pg_class tuple or not?
We need to understand that, too.  Maybe the old code never really
worked in all cases?  It seems clear that the commit you bisected to
just allowed a pre-existing misbehavior to become exposed (more easily).

No time to look closer right now.

			regards, tom lane



Commits

  1. Remove reindex_catalog test from test schedules.

  2. Remove RelationSetIndexList().

  3. Fix reindexing of pg_class indexes some more.

  4. Run catalog reindexing test from 3dbb317d32 serially, to avoid deadlocks.

  5. Fix potential assertion failure when reindexing a pg_class index.

  6. Fix several recently introduced issues around handling new relation forks.

  7. Avoid VACUUM FULL altogether in initdb.

  8. Introduce replication progress tracking infrastructure.

  9. initdb: remove unnecessary VACUUM FULL