diff options
Diffstat (limited to 'src/common/controldata_utils.c')
-rw-r--r-- | src/common/controldata_utils.c | 51 |
1 files changed, 42 insertions, 9 deletions
diff --git a/src/common/controldata_utils.c b/src/common/controldata_utils.c index 71e67a2edaa..567281349e0 100644 --- a/src/common/controldata_utils.c +++ b/src/common/controldata_utils.c @@ -29,7 +29,9 @@ #include "common/controldata_utils.h" #include "common/file_perm.h" #include "port/pg_crc32c.h" + #ifndef FRONTEND +#include "pgstat.h" #include "storage/fd.h" #endif @@ -144,13 +146,14 @@ get_controlfile(const char *DataDir, const char *progname, bool *crc_ok_p) * update_controlfile() * * Update controlfile values with the contents given by caller. The - * contents to write are included in "ControlFile". Note that it is up - * to the caller to fsync the updated file, and to properly lock - * ControlFileLock when calling this routine in the backend. + * contents to write are included in "ControlFile". "do_sync" can be + * optionally used to flush the updated control file. Note that it is up + * to the caller to properly lock ControlFileLock when calling this + * routine in the backend. */ void update_controlfile(const char *DataDir, const char *progname, - ControlFileData *ControlFile) + ControlFileData *ControlFile, bool do_sync) { int fd; char buffer[PG_CONTROL_FILE_SIZE]; @@ -182,7 +185,12 @@ update_controlfile(const char *DataDir, const char *progname, snprintf(ControlFilePath, sizeof(ControlFilePath), "%s/%s", DataDir, XLOG_CONTROL_FILE); #ifndef FRONTEND - if ((fd = OpenTransientFile(ControlFilePath, O_WRONLY | PG_BINARY)) == -1) + + /* + * All errors issue a PANIC, so no need to use OpenTransientFile() and to + * worry about file descriptor leaks. + */ + if ((fd = BasicOpenFile(ControlFilePath, O_RDWR | PG_BINARY)) < 0) ereport(PANIC, (errcode_for_file_access(), errmsg("could not open file \"%s\": %m", @@ -198,6 +206,9 @@ update_controlfile(const char *DataDir, const char *progname, #endif errno = 0; +#ifndef FRONTEND + pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE); +#endif if (write(fd, buffer, PG_CONTROL_FILE_SIZE) != PG_CONTROL_FILE_SIZE) { /* if write didn't set errno, assume problem is no disk space */ @@ -215,19 +226,41 @@ update_controlfile(const char *DataDir, const char *progname, exit(EXIT_FAILURE); #endif } +#ifndef FRONTEND + pgstat_report_wait_end(); +#endif + if (do_sync) + { +#ifndef FRONTEND + pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_SYNC_UPDATE); + if (pg_fsync(fd) != 0) + ereport(PANIC, + (errcode_for_file_access(), + errmsg("could not fsync file \"%s\": %m", + ControlFilePath))); + pgstat_report_wait_end(); +#else + if (fsync(fd) != 0) + { + fprintf(stderr, _("%s: could not fsync file \"%s\": %s\n"), + progname, ControlFilePath, strerror(errno)); + exit(EXIT_FAILURE); + } +#endif + } + + if (close(fd) < 0) + { #ifndef FRONTEND - if (CloseTransientFile(fd)) ereport(PANIC, (errcode_for_file_access(), errmsg("could not close file \"%s\": %m", ControlFilePath))); #else - if (close(fd) < 0) - { fprintf(stderr, _("%s: could not close file \"%s\": %s\n"), progname, ControlFilePath, strerror(errno)); exit(EXIT_FAILURE); - } #endif + } } |