It turns out that TablespaceCreateDbspace fails badly if a relcache flush
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 19 Jan 2006 04:45:58 +0000 (04:45 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 19 Jan 2006 04:45:58 +0000 (04:45 +0000)
commit2d67e13c9547c674bf86841ba0802005ebf5ab54
tree95c606ab6372947b01b10a56310715461ed9316d
parent41e09bbbad3a3506f7491d141208d68fa1d2488e
It turns out that TablespaceCreateDbspace fails badly if a relcache flush
occurs when it tries to heap_open pg_tablespace.  When control returns to
smgrcreate, that routine will be holding a dangling pointer to a closed
SMgrRelation, resulting in mayhem.  This is of course a consequence of
the violation of proper module layering inherent in having smgr.c call
a tablespace command routine, but the simplest fix seems to be to change
the locking mechanism.  There's no real need for TablespaceCreateDbspace
to touch pg_tablespace at all --- it's only opening it as a way of locking
against a parallel DROP TABLESPACE command.  A much better answer is to
create a special-purpose LWLock to interlock these two operations.
This drops TablespaceCreateDbspace quite a few layers down the food chain
and makes it something reasonably safe for smgr to call.
src/backend/commands/tablespace.c
src/include/storage/lwlock.h