aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/file/fd.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2002-08-06 02:36:35 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2002-08-06 02:36:35 +0000
commit5df307c7782518c4a3c19ffd05c7cb591b97e23c (patch)
tree0ff988dc5b7b115e9f6bbf29852dd4bad7fcaeea /src/backend/storage/file/fd.c
parent35cd432b185938c33967c9fa48223ce33e1c66bd (diff)
downloadpostgresql-5df307c7782518c4a3c19ffd05c7cb591b97e23c.tar.gz
postgresql-5df307c7782518c4a3c19ffd05c7cb591b97e23c.zip
Restructure local-buffer handling per recent pghackers discussion.
The local buffer manager is no longer used for newly-created relations (unless they are TEMP); a new non-TEMP relation goes through the shared bufmgr and thus will participate normally in checkpoints. But TEMP relations use the local buffer manager throughout their lifespan. Also, operations in TEMP relations are not logged in WAL, thus improving performance. Since it's no longer necessary to fsync relations as they move out of the local buffers into shared buffers, quite a lot of smgr.c/md.c/fd.c code is no longer needed and has been removed: there's no concept of a dirty relation anymore in md.c/fd.c, and we never fsync anything but WAL. Still TODO: improve local buffer management algorithms so that it would be reasonable to increase NLocBuffer.
Diffstat (limited to 'src/backend/storage/file/fd.c')
-rw-r--r--src/backend/storage/file/fd.c140
1 files changed, 3 insertions, 137 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 391a078e602..8be2ed219b9 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.92 2002/06/20 20:29:34 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.93 2002/08/06 02:36:34 tgl Exp $
*
* NOTES:
*
@@ -119,8 +119,7 @@ typedef struct vfd
unsigned short fdstate; /* bitflags for VFD's state */
/* these are the assigned bits in fdstate: */
-#define FD_DIRTY (1 << 0) /* written to, but not yet fsync'd */
-#define FD_TEMPORARY (1 << 1) /* should be unlinked when closed */
+#define FD_TEMPORARY (1 << 0) /* should be unlinked when closed */
File nextFree; /* link to next free VFD, if in freelist */
File lruMoreRecently; /* doubly linked recency-of-use list */
@@ -396,15 +395,6 @@ LruDelete(File file)
vfdP->seekPos = (long) lseek(vfdP->fd, 0L, SEEK_CUR);
Assert(vfdP->seekPos != -1L);
- /* if we have written to the file, sync it before closing */
- if (vfdP->fdstate & FD_DIRTY)
- {
- if (pg_fsync(vfdP->fd))
- elog(LOG, "LruDelete: failed to fsync %s: %m",
- vfdP->fileName);
- vfdP->fdstate &= ~FD_DIRTY;
- }
-
/* close the file */
if (close(vfdP->fd))
elog(LOG, "LruDelete: failed to close %s: %m",
@@ -725,17 +715,8 @@ fileNameOpenFile(FileName fileName,
/* Saved flags are adjusted to be OK for re-opening file */
vfdP->fileFlags = fileFlags & ~(O_CREAT | O_TRUNC | O_EXCL);
vfdP->fileMode = fileMode;
-
vfdP->seekPos = 0;
-
- /*
- * Have to fsync file on commit. Alternative way - log file creation
- * and fsync log before actual file creation.
- */
- if (fileFlags & O_CREAT)
- vfdP->fdstate = FD_DIRTY;
- else
- vfdP->fdstate = 0x0;
+ vfdP->fdstate = 0x0;
return file;
}
@@ -841,15 +822,6 @@ FileClose(File file)
/* remove the file from the lru ring */
Delete(file);
- /* if we did any writes, sync the file before closing */
- if (vfdP->fdstate & FD_DIRTY)
- {
- if (pg_fsync(vfdP->fd))
- elog(LOG, "FileClose: failed to fsync %s: %m",
- vfdP->fileName);
- vfdP->fdstate &= ~FD_DIRTY;
- }
-
/* close the file */
if (close(vfdP->fd))
elog(LOG, "FileClose: failed to close %s: %m",
@@ -1022,108 +994,11 @@ FileTruncate(File file, long offset)
DO_DB(elog(LOG, "FileTruncate %d (%s)",
file, VfdCache[file].fileName));
- FileSync(file);
FileAccess(file);
returnCode = ftruncate(VfdCache[file].fd, (size_t) offset);
return returnCode;
}
-/*
- * FileSync --- if a file is marked as dirty, fsync it.
- *
- * The FD_DIRTY bit is slightly misnamed: it doesn't mean that we need to
- * write the file, but that we *have* written it and need to execute an
- * fsync() to ensure the changes are down on disk before we mark the current
- * transaction committed.
- *
- * FD_DIRTY is set by FileWrite or by an explicit FileMarkDirty() call.
- * It is cleared after successfully fsync'ing the file. FileClose() will
- * fsync a dirty File that is about to be closed, since there will be no
- * other place to remember the need to fsync after the VFD is gone.
- *
- * Note that the DIRTY bit is logically associated with the actual disk file,
- * not with any particular kernel FD we might have open for it. We assume
- * that fsync will force out any dirty buffers for that file, whether or not
- * they were written through the FD being used for the fsync call --- they
- * might even have been written by some other backend!
- *
- * Note also that LruDelete currently fsyncs a dirty file that it is about
- * to close the kernel file descriptor for. The idea there is to avoid
- * having to re-open the kernel descriptor later. But it's not real clear
- * that this is a performance win; we could end up fsyncing the same file
- * multiple times in a transaction, which would probably cost more time
- * than is saved by avoiding an open() call. This should be studied.
- *
- * This routine used to think it could skip the fsync if the file is
- * physically closed, but that is now WRONG; see comments for FileMarkDirty.
- */
-int
-FileSync(File file)
-{
- int returnCode;
-
- Assert(FileIsValid(file));
-
- if (!(VfdCache[file].fdstate & FD_DIRTY))
- {
- /* Need not sync if file is not dirty. */
- returnCode = 0;
- }
- else if (!enableFsync)
- {
- /* Don't force the file open if pg_fsync isn't gonna sync it. */
- returnCode = 0;
- VfdCache[file].fdstate &= ~FD_DIRTY;
- }
- else
- {
- /*
- * We don't use FileAccess() because we don't want to force the
- * file to the front of the LRU ring; we aren't expecting to
- * access it again soon.
- */
- if (FileIsNotOpen(file))
- {
- returnCode = LruInsert(file);
- if (returnCode != 0)
- return returnCode;
- }
- returnCode = pg_fsync(VfdCache[file].fd);
- if (returnCode == 0)
- VfdCache[file].fdstate &= ~FD_DIRTY;
- }
-
- return returnCode;
-}
-
-/*
- * FileMarkDirty --- mark a file as needing fsync at transaction commit.
- *
- * Since FileWrite marks the file dirty, this routine is not needed in
- * normal use. It is called when the buffer manager detects that some other
- * backend has written out a shared buffer that this backend dirtied (but
- * didn't write) in the current xact. In that scenario, we need to fsync
- * the file before we can commit. We cannot assume that the other backend
- * has fsync'd the file yet; we need to do our own fsync to ensure that
- * (a) the disk page is written and (b) this backend's commit is delayed
- * until the write is complete.
- *
- * Note we are assuming that an fsync issued by this backend will write
- * kernel disk buffers that were dirtied by another backend. Furthermore,
- * it doesn't matter whether we currently have the file physically open;
- * we must fsync even if we have to re-open the file to do it.
- */
-void
-FileMarkDirty(File file)
-{
- Assert(FileIsValid(file));
-
- DO_DB(elog(LOG, "FileMarkDirty: %d (%s)",
- file, VfdCache[file].fileName));
-
- VfdCache[file].fdstate |= FD_DIRTY;
-}
-
/*
* Routines that want to use stdio (ie, FILE*) should use AllocateFile
@@ -1142,7 +1017,6 @@ FileMarkDirty(File file)
*
* Ideally this should be the *only* direct call of fopen() in the backend.
*/
-
FILE *
AllocateFile(char *name, char *mode)
{
@@ -1229,12 +1103,6 @@ closeAllVfds(void)
* exit (it doesn't particularly care which). All still-open temporary-file
* VFDs are closed, which also causes the underlying files to be deleted.
* Furthermore, all "allocated" stdio files are closed.
- *
- * This routine is not involved in fsync'ing non-temporary files at xact
- * commit; that is done by FileSync under control of the buffer manager.
- * During a commit, that is done *before* control gets here. If we still
- * have any needs-fsync bits set when we get here, we assume this is abort
- * and clear them.
*/
void
AtEOXact_Files(void)
@@ -1249,8 +1117,6 @@ AtEOXact_Files(void)
if ((VfdCache[i].fdstate & FD_TEMPORARY) &&
VfdCache[i].fileName != NULL)
FileClose(i);
- else
- VfdCache[i].fdstate &= ~FD_DIRTY;
}
}