1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Code review for holdable-cursors patch. Fix error recovery, memory

context sloppiness, some other things.  Includes Neil's mopup patch
of 22-Apr.
This commit is contained in:
Tom Lane
2003-04-29 03:21:30 +00:00
parent 6a17d226b5
commit 4a5f38c4e6
18 changed files with 379 additions and 316 deletions

View File

@ -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.97 2003/04/04 20:42:12 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/storage/file/fd.c,v 1.98 2003/04/29 03:21:29 tgl Exp $
*
* NOTES:
*
@ -113,8 +113,8 @@ int max_files_per_process = 1000;
#define FileUnknownPos (-1L)
/* these are the assigned bits in fdstate below: */
#define FD_TEMPORARY (1 << 0)
#define FD_TXN_TEMPORARY (1 << 1)
#define FD_TEMPORARY (1 << 0) /* T = delete when closed */
#define FD_XACT_TEMPORARY (1 << 1) /* T = delete at eoXact */
typedef struct vfd
{
@ -156,7 +156,7 @@ static int numAllocatedFiles = 0;
static FILE *allocatedFiles[MAX_ALLOCATED_FILES];
/*
* Number of temporary files opened during the current transaction;
* Number of temporary files opened during the current session;
* this is used in generation of tempfile names.
*/
static long tempFileCounter = 0;
@ -205,6 +205,9 @@ static int FileAccess(File file);
static File fileNameOpenFile(FileName fileName, int fileFlags, int fileMode);
static char *filepath(const char *filename);
static long pg_nofile(void);
static void AtProcExit_Files(void);
static void CleanupTempFiles(bool isProcExit);
/*
* pg_fsync --- same as fsync except does nothing if enableFsync is off
@ -522,7 +525,7 @@ AllocateVfd(void)
* register proc-exit call to ensure temp files are dropped at
* exit
*/
on_proc_exit(AtEOXact_Files, 0);
on_proc_exit(AtProcExit_Files, 0);
}
if (VfdCache[0].nextFree == 0)
@ -751,21 +754,21 @@ PathNameOpenFile(FileName fileName, int fileFlags, int fileMode)
* There's no need to pass in fileFlags or fileMode either, since only
* one setting makes any sense for a temp file.
*
* keepOverTxn: if true, don't close the file at end-of-transaction. In
* interXact: if true, don't close the file at end-of-transaction. In
* most cases, you don't want temporary files to outlive the transaction
* that created them, so this should be false -- but if you need
* "somewhat" temporary storage, this might be useful. In either case,
* the file is removed when the File is explicitely closed.
* the file is removed when the File is explicitly closed.
*/
File
OpenTemporaryFile(bool keepOverTxn)
OpenTemporaryFile(bool interXact)
{
char tempfilepath[128];
char tempfilepath[MAXPGPATH];
File file;
/*
* Generate a tempfile name that's unique within the current
* transaction and database instance.
* Generate a tempfile name that should be unique within the current
* database instance.
*/
snprintf(tempfilepath, sizeof(tempfilepath),
"%s/%s%d.%ld", PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
@ -798,15 +801,16 @@ OpenTemporaryFile(bool keepOverTxn)
O_RDWR | O_CREAT | O_TRUNC | PG_BINARY,
0600);
if (file <= 0)
elog(ERROR, "Failed to create temporary file %s", tempfilepath);
elog(ERROR, "Failed to create temporary file %s: %m",
tempfilepath);
}
/* Mark it for deletion at close */
VfdCache[file].fdstate |= FD_TEMPORARY;
/* Mark it for deletion at EOXact */
if (!keepOverTxn)
VfdCache[file].fdstate |= FD_TXN_TEMPORARY;
if (!interXact)
VfdCache[file].fdstate |= FD_XACT_TEMPORARY;
return file;
}
@ -1108,44 +1112,79 @@ closeAllVfds(void)
/*
* AtEOXact_Files
*
* This routine is called during transaction commit or abort or backend
* 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 called during transaction commit or abort (it doesn't
* particularly care which). All still-open per-transaction temporary file
* VFDs are closed, which also causes the underlying files to be
* deleted. Furthermore, all "allocated" stdio files are closed.
*/
void
AtEOXact_Files(void)
{
Index i;
CleanupTempFiles(false);
}
/*
* AtProcExit_Files
*
* on_proc_exit hook to clean up temp files during backend shutdown.
* Here, we want to clean up *all* temp files including interXact ones.
*/
static void
AtProcExit_Files(void)
{
CleanupTempFiles(true);
}
/*
* Close temporary files and delete their underlying files.
*
* isProcExit: if true, this is being called as the backend process is
* exiting. If that's the case, we should remove all temporary files; if
* that's not the case, we are being called for transaction commit/abort
* and should only remove transaction-local temp files. In either case,
* also clean up "allocated" stdio files.
*/
static void
CleanupTempFiles(bool isProcExit)
{
Index i;
if (SizeVfdCache > 0)
{
Assert(FileIsNotOpen(0)); /* Make sure ring not corrupted */
for (i = 1; i < SizeVfdCache; i++)
{
if ((VfdCache[i].fdstate & FD_TEMPORARY) &&
(VfdCache[i].fdstate & FD_TXN_TEMPORARY) &&
VfdCache[i].fileName != NULL)
FileClose(i);
unsigned short fdstate = VfdCache[i].fdstate;
if ((fdstate & FD_TEMPORARY) && VfdCache[i].fileName != NULL)
{
/*
* If we're in the process of exiting a backend process,
* close all temporary files. Otherwise, only close
* temporary files local to the current transaction.
*/
if (isProcExit || (fdstate & FD_XACT_TEMPORARY))
FileClose(i);
}
}
}
while (numAllocatedFiles > 0)
FreeFile(allocatedFiles[0]);
/*
* Reset the tempfile name counter to 0; not really necessary, but
* helps keep the names from growing unreasonably long.
*/
tempFileCounter = 0;
}
/*
* Remove old temporary files
* Remove temporary files left over from a prior postmaster session
*
* This should be called during postmaster startup. It will forcibly
* remove any leftover files created by OpenTemporaryFile.
*
* NOTE: we could, but don't, call this during a post-backend-crash restart
* cycle. The argument for not doing it is that someone might want to examine
* the temp files for debugging purposes. This does however mean that
* OpenTemporaryFile had better allow for collision with an existing temp
* file name.
*/
void
RemovePgTempFiles(void)
@ -1194,15 +1233,9 @@ RemovePgTempFiles(void)
strlen(PG_TEMP_FILE_PREFIX)) == 0)
unlink(rm_path);
else
{
/*
* would prefer to use elog here, but it's not up
* and running during postmaster startup...
*/
fprintf(stderr,
"Unexpected file found in temporary-files directory: %s\n",
rm_path);
}
elog(LOG,
"Unexpected file found in temporary-files directory: %s",
rm_path);
}
closedir(temp_dir);
}