From 44965db6004a8fce320ac09519e4b49d7243ae40 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Thu, 7 Jul 2022 16:30:26 +0530 Subject: [PATCH v7 3/4] Assert checking (to be merged with 0002) --- src/backend/catalog/catalog.c | 54 ++++++++++++++++++++++++++++++++++++++++ src/backend/catalog/heap.c | 5 ++++ src/backend/catalog/storage.c | 6 +++++ src/backend/commands/tablecmds.c | 3 +++ src/include/catalog/catalog.h | 9 +++++++ 5 files changed, 77 insertions(+) diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c index 155400c..9a22203 100644 --- a/src/backend/catalog/catalog.c +++ b/src/backend/catalog/catalog.c @@ -583,3 +583,57 @@ pg_stop_making_pinned_objects(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } + +#ifdef USE_ASSERT_CHECKING + +/* + * Assert that there is no existing diskfile for input relnumber. + */ +void +AssertRelfileNumberFileNotExists(Oid spcoid, RelFileNumber relnumber, + char relpersistence) +{ + RelFileLocatorBackend rlocator; + char *rpath; + BackendId backend; + + /* + * If we ever get here during pg_upgrade, there's something wrong; all + * relfilenode assignments during a binary-upgrade run should be + * determined by commands in the dump script. + */ + Assert(!IsBinaryUpgrade); + + switch (relpersistence) + { + case RELPERSISTENCE_TEMP: + backend = BackendIdForTempRelations(); + break; + case RELPERSISTENCE_UNLOGGED: + case RELPERSISTENCE_PERMANENT: + backend = InvalidBackendId; + break; + default: + elog(ERROR, "invalid relpersistence: %c", relpersistence); + return; /* placate compiler */ + } + + /* this logic should match RelationInitPhysicalAddr */ + rlocator.locator.spcOid = spcoid ? spcoid : MyDatabaseTableSpace; + rlocator.locator.dbOid = + (rlocator.locator.spcOid == GLOBALTABLESPACE_OID) ? InvalidOid : + MyDatabaseId; + + /* + * The relpath will vary based on the backend ID, so we must initialize + * that properly here to make sure that any collisions based on filename + * are properly detected. + */ + rlocator.backend = backend; + + /* check for existing file of same name. */ + rpath = relpath(rlocator, MAIN_FORKNUM); + + Assert(access(rpath, F_OK) != 0); +} +#endif \ No newline at end of file diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 955ae3b..30fd15c 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -345,7 +345,12 @@ heap_create(const char *relname, * with oid same as relid. */ if (!RelFileNumberIsValid(relfilenumber)) + { relfilenumber = GetNewRelFileNumber(); + AssertRelfileNumberFileNotExists(reltablespace, + relfilenumber, + relpersistence); + } } /* diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c index d708af1..db85bd8 100644 --- a/src/backend/catalog/storage.c +++ b/src/backend/catalog/storage.c @@ -968,6 +968,9 @@ smgr_redo(XLogReaderState *record) xl_smgr_create *xlrec = (xl_smgr_create *) XLogRecGetData(record); SMgrRelation reln; + Assert(xlrec->rlocator.relNumber <= + ShmemVariableCache->nextRelFileNumber); + reln = smgropen(xlrec->rlocator, InvalidBackendId); smgrcreate(reln, xlrec->forkNum, true); } @@ -981,6 +984,9 @@ smgr_redo(XLogReaderState *record) int nforks = 0; bool need_fsm_vacuum = false; + Assert(xlrec->rlocator.relNumber <= + ShmemVariableCache->nextRelFileNumber); + reln = smgropen(xlrec->rlocator, InvalidBackendId); /* diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3f48523..0678681 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -14377,6 +14377,9 @@ ATExecSetTableSpace(Oid tableOid, Oid newTableSpace, LOCKMODE lockmode) * will get the conflicting relfilenumber file. */ newrelfilenumber = GetNewRelFileNumber(); + AssertRelfileNumberFileNotExists(newTableSpace, + newrelfilenumber, + rel->rd_rel->relpersistence); /* Open old and new relation */ newrlocator = rel->rd_locator; diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h index b452530..be6ba13 100644 --- a/src/include/catalog/catalog.h +++ b/src/include/catalog/catalog.h @@ -39,4 +39,13 @@ extern bool IsPinnedObject(Oid classId, Oid objectId); extern Oid GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn); +#ifdef USE_ASSERT_CHECKING +extern void AssertRelfileNumberFileNotExists(Oid spcoid, + RelFileNumber relnumber, + char relpersistence); +#else +#define AssertRelfileNumberFileNotExists(spcoid, relnumber, relpersistence) \ + ((void)true) +#endif + #endif /* CATALOG_H */ -- 1.8.3.1