It turns out that TablespaceCreateDbspace fails badly if a relcache flush
Tom Lane <tgl@sss.pgh.pa.us>
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.
Files
| Path | Change | +/− |
|---|---|---|
| src/backend/commands/tablespace.c | modified | +25 −29 |
| src/include/storage/lwlock.h | modified | +2 −1 |