From 8b938d36f7446e76436ca4a8ddcebbebaeaab480 Mon Sep 17 00:00:00 2001 From: Michael Paquier Date: Mon, 18 Mar 2019 12:59:35 +0900 Subject: Refactor more code logic to update the control file ce6afc6 has begun the refactoring work by plugging pg_rewind into a central routine to update the control file, and left around two extra copies, with one in xlog.c for the backend and one in pg_resetwal.c. By adding an extra option to the central routine in controldata_utils.c to control if a flush of the control file needs to be done, it is proving to be straight-forward to make xlog.c and pg_resetwal.c use the central code path at the condition of moving the wait event tracking there. Hence, this allows to have only one central code path to update the control file, shaving the code from the duplicates. This refactoring actually fixes a problem in pg_resetwal. Previously, the control file was first removed before being recreated. So if a crash happened between the moment the file was removed and the moment the file was created, then it would have been possible to not have a control file anymore in the database folder. Author: Fabien Coelho Reviewed-by: Michael Paquier Discussion: https://postgr.es/m/alpine.DEB.2.21.1903170935210.2506@lancre --- src/backend/access/transam/xlog.c | 48 +++++---------------------------------- 1 file changed, 6 insertions(+), 42 deletions(-) (limited to 'src/backend/access/transam/xlog.c') diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 54d3c558c64..ad12ebc4269 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -40,6 +40,7 @@ #include "catalog/pg_control.h" #include "catalog/pg_database.h" #include "commands/tablespace.h" +#include "common/controldata_utils.h" #include "miscadmin.h" #include "pgstat.h" #include "port/atomics.h" @@ -4754,51 +4755,14 @@ ReadControlFile(void) PGC_INTERNAL, PGC_S_OVERRIDE); } +/* + * Utility wrapper to update the control file. Note that the control + * file gets flushed. + */ void UpdateControlFile(void) { - int fd; - - INIT_CRC32C(ControlFile->crc); - COMP_CRC32C(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32C(ControlFile->crc); - - fd = BasicOpenFile(XLOG_CONTROL_FILE, - O_RDWR | PG_BINARY); - if (fd < 0) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not open file \"%s\": %m", XLOG_CONTROL_FILE))); - - errno = 0; - pgstat_report_wait_start(WAIT_EVENT_CONTROL_FILE_WRITE_UPDATE); - if (write(fd, ControlFile, sizeof(ControlFileData)) != sizeof(ControlFileData)) - { - /* if write didn't set errno, assume problem is no disk space */ - if (errno == 0) - errno = ENOSPC; - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not write to file \"%s\": %m", - XLOG_CONTROL_FILE))); - } - pgstat_report_wait_end(); - - 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", - XLOG_CONTROL_FILE))); - pgstat_report_wait_end(); - - if (close(fd)) - ereport(PANIC, - (errcode_for_file_access(), - errmsg("could not close file \"%s\": %m", - XLOG_CONTROL_FILE))); + update_controlfile(DataDir, NULL, ControlFile, true); } /* -- cgit v1.2.3