aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/storage/file/fd.c57
-rw-r--r--src/backend/utils/init/postinit.c15
-rw-r--r--src/include/storage/fd.h1
3 files changed, 65 insertions, 8 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 5d5e8ae94e0..b58b3998345 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -231,6 +231,11 @@ static bool have_xact_temporary_files = false;
*/
static uint64 temporary_files_size = 0;
+/* Temporary file access initialized and not yet shut down? */
+#ifdef USE_ASSERT_CHECKING
+static bool temporary_files_allowed = false;
+#endif
+
/*
* List of OS handles opened with AllocateFile, AllocateDir and
* OpenTransientFile.
@@ -327,7 +332,7 @@ static File OpenTemporaryFileInTablespace(Oid tblspcOid, bool rejectError);
static bool reserveAllocatedDesc(void);
static int FreeDesc(AllocateDesc *desc);
-static void AtProcExit_Files(int code, Datum arg);
+static void BeforeShmemExit_Files(int code, Datum arg);
static void CleanupTempFiles(bool isCommit, bool isProcExit);
static void RemovePgTempRelationFiles(const char *tsdirname);
static void RemovePgTempRelationFilesInDbspace(const char *dbspacedirname);
@@ -868,6 +873,9 @@ durable_rename_excl(const char *oldfile, const char *newfile, int elevel)
*
* This is called during either normal or standalone backend start.
* It is *not* called in the postmaster.
+ *
+ * Note that this does not initialize temporary file access, that is
+ * separately initialized via InitTemporaryFileAccess().
*/
void
InitFileAccess(void)
@@ -885,9 +893,35 @@ InitFileAccess(void)
VfdCache->fd = VFD_CLOSED;
SizeVfdCache = 1;
+}
+
+/*
+ * InitTemporaryFileAccess --- initialize temporary file access during startup
+ *
+ * This is called during either normal or standalone backend start.
+ * It is *not* called in the postmaster.
+ *
+ * This is separate from InitFileAccess() because temporary file cleanup can
+ * cause pgstat reporting. As pgstat is shut down during before_shmem_exit(),
+ * our reporting has to happen before that. Low level file access should be
+ * available for longer, hence the separate initialization / shutdown of
+ * temporary file handling.
+ */
+void
+InitTemporaryFileAccess(void)
+{
+ Assert(SizeVfdCache != 0); /* InitFileAccess() needs to have run*/
+ Assert(!temporary_files_allowed); /* call me only once */
+
+ /*
+ * Register before-shmem-exit hook to ensure temp files are dropped while
+ * we can still report stats.
+ */
+ before_shmem_exit(BeforeShmemExit_Files, 0);
- /* register proc-exit hook to ensure temp files are dropped at exit */
- on_proc_exit(AtProcExit_Files, 0);
+#ifdef USE_ASSERT_CHECKING
+ temporary_files_allowed = true;
+#endif
}
/*
@@ -1670,6 +1704,8 @@ OpenTemporaryFile(bool interXact)
{
File file = 0;
+ Assert(temporary_files_allowed); /* check temp file access is up */
+
/*
* Make sure the current resource owner has space for this File before we
* open it, if we'll be registering it below.
@@ -1805,6 +1841,8 @@ PathNameCreateTemporaryFile(const char *path, bool error_on_failure)
{
File file;
+ Assert(temporary_files_allowed); /* check temp file access is up */
+
ResourceOwnerEnlargeFiles(CurrentResourceOwner);
/*
@@ -1843,6 +1881,8 @@ PathNameOpenTemporaryFile(const char *path, int mode)
{
File file;
+ Assert(temporary_files_allowed); /* check temp file access is up */
+
ResourceOwnerEnlargeFiles(CurrentResourceOwner);
file = PathNameOpenFile(path, mode | PG_BINARY);
@@ -3004,15 +3044,20 @@ AtEOXact_Files(bool isCommit)
}
/*
- * AtProcExit_Files
+ * BeforeShmemExit_Files
*
- * on_proc_exit hook to clean up temp files during backend shutdown.
+ * before_shmem_access 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(int code, Datum arg)
+BeforeShmemExit_Files(int code, Datum arg)
{
CleanupTempFiles(false, true);
+
+ /* prevent further temp files from being created */
+#ifdef USE_ASSERT_CHECKING
+ temporary_files_allowed = false;
+#endif
}
/*
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 87dc060b201..5089dd43ae2 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -518,6 +518,12 @@ BaseInit(void)
DebugFileOpen();
/*
+ * Initialize file access. Done early so other subsystems can access
+ * files.
+ */
+ InitFileAccess();
+
+ /*
* Initialize statistics reporting. This needs to happen early to ensure
* that pgstat's shutdown callback runs after the shutdown callbacks of
* all subsystems that can produce stats (like e.g. transaction commits
@@ -525,11 +531,16 @@ BaseInit(void)
*/
pgstat_initialize();
- /* Do local initialization of file, storage and buffer managers */
- InitFileAccess();
+ /* Do local initialization of storage and buffer managers */
InitSync();
smgrinit();
InitBufferPoolAccess();
+
+ /*
+ * Initialize temporary file access after pgstat, so that the temorary
+ * file shutdown hook can report temporary file statistics.
+ */
+ InitTemporaryFileAccess();
}
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 2d843eb9929..34602ae0069 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -158,6 +158,7 @@ extern int MakePGDirectory(const char *directoryName);
/* Miscellaneous support routines */
extern void InitFileAccess(void);
+extern void InitTemporaryFileAccess(void);
extern void set_max_safe_fds(void);
extern void closeAllVfds(void);
extern void SetTempTablespaces(Oid *tableSpaces, int numSpaces);