summaryrefslogtreecommitdiff
path: root/src/backend/utils/init/checkfiles.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/init/checkfiles.c')
-rw-r--r--src/backend/utils/init/checkfiles.c205
1 files changed, 0 insertions, 205 deletions
diff --git a/src/backend/utils/init/checkfiles.c b/src/backend/utils/init/checkfiles.c
deleted file mode 100644
index 8ed5110d73c..00000000000
--- a/src/backend/utils/init/checkfiles.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * checkfiles.c
- * check for stale relation files during crash recovery
- *
- * If a backend crashes while in a transaction that has created or
- * deleted a relfilenode, a stale file can be left over in the data
- * directory. This file contains routines to clean up those stale
- * files on recovery.
- *
- * This adds a 17% increase in startup cost for 100 empty databases. bjm
- * One optimization would be to create a 'dirty' file on a postmaster recovery
- * and remove the dirty flag only when a clean startup detects no unreferenced
- * files, and use the 'dirty' flag to determine if we should run this on
- * a clean startup.
- *
- * $PostgreSQL: pgsql/src/backend/utils/init/checkfiles.c,v 1.2 2005/05/05 22:18:27 tgl Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "access/heapam.h"
-#include "access/relscan.h"
-#include "access/skey.h"
-#include "catalog/catalog.h"
-#include "catalog/pg_tablespace.h"
-#include "miscadmin.h"
-#include "storage/fd.h"
-#include "utils/flatfiles.h"
-#include "utils/fmgroids.h"
-#include "utils/resowner.h"
-
-
-static void CheckStaleRelFilesFrom(Oid tablespaceoid, Oid dboid);
-static void CheckStaleRelFilesFromTablespace(Oid tablespaceoid);
-
-/* Like AllocateDir, but ereports on failure */
-static DIR *
-AllocateDirChecked(char *path)
-{
- DIR *dirdesc = AllocateDir(path);
-
- if (dirdesc == NULL)
- ereport(ERROR,
- (errcode_for_file_access(),
- errmsg("could not open directory \"%s\": %m",
- path)));
- return dirdesc;
-}
-
-/*
- * Scan through all tablespaces for relations left over
- * by aborted transactions.
- */
-void
-CheckStaleRelFiles(void)
-{
- DIR *dirdesc;
- struct dirent *de;
- char *path;
- int pathlen;
-
- pathlen = strlen(DataDir) + 11 + 1;
- path = (char *) palloc(pathlen);
- snprintf(path, pathlen, "%s/pg_tblspc/", DataDir);
- dirdesc = AllocateDirChecked(path);
- while ((de = readdir(dirdesc)) != NULL)
- {
- char *invalid;
- Oid tablespaceoid;
-
- /* Check that the directory name looks like valid tablespace link. */
- tablespaceoid = (Oid) strtol(de->d_name, &invalid, 10);
- if (invalid[0] == '\0')
- CheckStaleRelFilesFromTablespace(tablespaceoid);
- }
- FreeDir(dirdesc);
- pfree(path);
-
- CheckStaleRelFilesFromTablespace(DEFAULTTABLESPACE_OID);
-}
-
-/* Scan a specific tablespace for stale relations */
-static void
-CheckStaleRelFilesFromTablespace(Oid tablespaceoid)
-{
- DIR *dirdesc;
- struct dirent *de;
- char *path;
-
- path = GetTablespacePath(tablespaceoid);
-
- dirdesc = AllocateDirChecked(path);
- while ((de = readdir(dirdesc)) != NULL)
- {
- char *invalid;
- Oid dboid;
-
- dboid = (Oid) strtol(de->d_name, &invalid, 10);
- if (invalid[0] == '\0')
- CheckStaleRelFilesFrom(tablespaceoid, dboid);
- }
- FreeDir(dirdesc);
- pfree(path);
-}
-
-/* Scan a specific database in a specific tablespace for stale relations.
- *
- * First, pg_class for the database is opened, and the relfilenodes of all
- * relations mentioned there are stored in a hash table.
- *
- * Then the directory is scanned. Every file in the directory that's not
- * found in pg_class (the hash table) is logged.
- */
-static void
-CheckStaleRelFilesFrom(Oid tablespaceoid, Oid dboid)
-{
- DIR *dirdesc;
- struct dirent *de;
- HASHCTL hashctl;
- HTAB *relfilenodeHash;
- RelFileNode rnode;
- char *path;
-
- /*
- * The entry contents is not used for anything, we just check if an oid is
- * in the hash table or not.
- */
- hashctl.keysize = sizeof(Oid);
- hashctl.entrysize = sizeof(Oid);
- hashctl.hash = tag_hash;
- relfilenodeHash = hash_create("relfilenodeHash", 100, &hashctl,
- HASH_FUNCTION | HASH_ELEM);
-
- /* Read all relfilenodes from pg_class into the hash table */
- {
- ResourceOwner owner,
- oldowner;
- Relation rel;
- HeapScanDesc scan;
- HeapTuple tuple;
-
- /* Need a resowner to keep the heapam and buffer code happy */
- owner = ResourceOwnerCreate(NULL, "CheckStaleRelFiles");
- oldowner = CurrentResourceOwner;
- CurrentResourceOwner = owner;
-
- rnode.spcNode = tablespaceoid;
- rnode.dbNode = dboid;
- rnode.relNode = RelationRelationId;
- rel = XLogOpenRelation(true, 0, rnode);
-
- scan = heap_beginscan(rel, SnapshotNow, 0, NULL);
- while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
- {
- Form_pg_class classform = (Form_pg_class) GETSTRUCT(tuple);
-
- hash_search(relfilenodeHash, &classform->relfilenode,
- HASH_ENTER, NULL);
- }
- heap_endscan(scan);
-
- XLogCloseRelation(rnode);
- CurrentResourceOwner = oldowner;
- ResourceOwnerDelete(owner);
- }
-
- /* Scan the directory */
- path = GetDatabasePath(dboid, tablespaceoid);
-
- dirdesc = AllocateDirChecked(path);
- while ((de = readdir(dirdesc)) != NULL)
- {
- char *invalid;
- Oid relfilenode;
-
- relfilenode = strtol(de->d_name, &invalid, 10);
- if (invalid[0] == '\0')
- {
- /*
- * Filename was a valid number, check if pg_class knows about it
- */
- if (hash_search(relfilenodeHash, &relfilenode,
- HASH_FIND, NULL) == NULL)
- {
- char *filepath;
-
- rnode.spcNode = tablespaceoid;
- rnode.dbNode = dboid;
- rnode.relNode = relfilenode;
-
- filepath = relpath(rnode);
- ereport(LOG,
- (errcode_for_file_access(),
- errmsg("table or index file \"%s\" is stale and can safely be removed",
- filepath)));
- pfree(filepath);
- }
- }
- }
- FreeDir(dirdesc);
- pfree(path);
- hash_destroy(relfilenodeHash);
-}