/* * RelationDropStorage * Schedule unlinking of physical storage at transaction commit. */ void RelationDropStorage(Relation rel) { PendingRelDelete *pending; /* Add the relation to the list of stuff to delete at commit */ pending = (PendingRelDelete *) MemoryContextAlloc(TopMemoryContext, sizeof(PendingRelDelete)); pending->relnode = rel->rd_node; pending->isTemp = rel->rd_istemp; pending->atCommit = true; /* delete if commit */ pending->nestLevel = GetCurrentTransactionNestLevel(); pending->next = pendingDeletes; pendingDeletes = pending; /* * NOTE: if the relation was created in this transaction, it will now be * present in the pending-delete list twice, once with atCommit true and * once with atCommit false. Hence, it will be physically deleted at end * of xact in either case (and the other entry will be ignored by * smgrDoPendingDeletes, so no error will occur). We could instead remove * the existing list entry and delete the physical file immediately, but * for now I'll keep the logic simple. */ RelationCloseSmgr(rel); }
void DirectOpen_Close( DirectOpen *direct, Relation rel) { Assert(rel == &direct->relationData); Assert (direct->isInit); RelationCloseSmgr(&direct->relationData); Assert(direct->relationData.rd_refcnt > 0); direct->relationData.rd_refcnt--; }
/* * Close a relation during XLOG replay * * This is called when the relation is about to be deleted; we need to ensure * that there is no dangling smgr reference in the xlog relation cache. * * Currently, we don't bother to physically remove the relation from the * cache, we just let it age out normally. */ void XLogCloseRelation(RelFileNode rnode) { XLogRelDesc *rdesc; XLogRelCacheEntry *hentry; hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, NULL); if (!hentry) return; /* not in cache so no work */ rdesc = hentry->rdesc; RelationCloseSmgr(&(rdesc->reldata)); }
/* * Drop a relation during XLOG replay * * This is called when the relation is about to be deleted; we need to ensure * that there is no dangling smgr reference in the xlog relation cache. * * Currently, we don't bother to physically remove the relation from the * cache, we just let it age out normally. * * This also takes care of removing any open "invalid-page" records for * the relation. */ void XLogDropRelation(RelFileNode rnode) { XLogRelCacheEntry *hentry; hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache, (void *) &rnode, HASH_FIND, NULL); if (hentry) { XLogRelDesc *rdesc = hentry->rdesc; RelationCloseSmgr(&(rdesc->reldata)); } forget_invalid_pages(rnode, 0); }
/* * Drop a whole database during XLOG replay * * As above, but for DROP DATABASE instead of dropping a single rel */ void XLogDropDatabase(Oid dbid) { HASH_SEQ_STATUS status; XLogRelCacheEntry *hentry; hash_seq_init(&status, _xlrelcache); while ((hentry = (XLogRelCacheEntry *) hash_seq_search(&status)) != NULL) { XLogRelDesc *rdesc = hentry->rdesc; if (hentry->rnode.dbNode == dbid) RelationCloseSmgr(&(rdesc->reldata)); } forget_invalid_pages_db(dbid); }
static void _xl_remove_hash_entry(XLogRelDesc *rdesc) { Form_pg_class tpgc = rdesc->reldata.rd_rel; XLogRelCacheEntry *hentry; rdesc->lessRecently->moreRecently = rdesc->moreRecently; rdesc->moreRecently->lessRecently = rdesc->lessRecently; hentry = (XLogRelCacheEntry *) hash_search(_xlrelcache, (void *) &(rdesc->reldata.rd_node), HASH_REMOVE, NULL); if (hentry == NULL) elog(PANIC, "_xl_remove_hash_entry: file was not found in cache"); RelationCloseSmgr(&(rdesc->reldata)); memset(rdesc, 0, sizeof(XLogRelDesc)); memset(tpgc, 0, sizeof(FormData_pg_class)); rdesc->reldata.rd_rel = tpgc; }