Attached is v2 of the patch, that

(a) adds explicit fsync on the parent directory after all the rename()
    calls in timeline.c, xlog.c, xlogarchive.c and pgarch.c

(b) adds START/END_CRIT_SECTION around the new fsync_fname calls
    (except for those in timeline.c, as the START/END_CRIT_SECTION is
    not available there)

The patch is fairly trivial and I've done some rudimentary testing, but I'm sure I haven't exercised all the modified paths.

regards
Tomas

--
Tomas Vondra                  http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services
diff --git a/src/backend/access/transam/timeline.c b/src/backend/access/transam/timeline.c
index c6862a8..998e50b 100644
--- a/src/backend/access/transam/timeline.c
+++ b/src/backend/access/transam/timeline.c
@@ -437,6 +437,9 @@ writeTimeLineHistory(TimeLineID newTLI, TimeLineID parentTLI,
 						tmppath, path)));
 #endif
 
+	/* Make sure the rename is permanent by fyncing the directory. */
+	fsync_fname(XLOGDIR, true);
+
 	/* The history file can be archived immediately. */
 	if (XLogArchivingActive())
 	{
@@ -526,6 +529,9 @@ writeTimeLineHistoryFile(TimeLineID tli, char *content, int size)
 				 errmsg("could not rename file \"%s\" to \"%s\": %m",
 						tmppath, path)));
 #endif
+
+	/* Make sure the rename is permanent by fyncing the directory. */
+	fsync_fname(XLOGDIR, true);
 }
 
 /*
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index f17f834..de24a09 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -3282,6 +3282,10 @@ InstallXLogFileSegment(XLogSegNo *segno, char *tmppath,
 	}
 #endif
 
+	START_CRIT_SECTION();
+	fsync_fname(XLOGDIR, true);
+	END_CRIT_SECTION();
+
 	if (use_lock)
 		LWLockRelease(ControlFileLock);
 
@@ -3806,6 +3810,11 @@ RemoveXlogFile(const char *segname, XLogRecPtr PriorRedoPtr, XLogRecPtr endptr)
 #else
 		rc = unlink(path);
 #endif
+
+		START_CRIT_SECTION();
+		fsync_fname(XLOGDIR, true);
+		END_CRIT_SECTION();
+
 		if (rc != 0)
 		{
 			ereport(LOG,
@@ -5302,6 +5311,10 @@ exitArchiveRecovery(TimeLineID endTLI, XLogRecPtr endOfLog)
 				 errmsg("could not rename file \"%s\" to \"%s\": %m",
 						RECOVERY_COMMAND_FILE, RECOVERY_COMMAND_DONE)));
 
+	START_CRIT_SECTION();
+	fsync_fname(".", true);
+	END_CRIT_SECTION();
+
 	ereport(LOG,
 			(errmsg("archive recovery complete")));
 }
@@ -6155,6 +6168,11 @@ StartupXLOG(void)
 								TABLESPACE_MAP, BACKUP_LABEL_FILE),
 						 errdetail("Could not rename file \"%s\" to \"%s\": %m.",
 								   TABLESPACE_MAP, TABLESPACE_MAP_OLD)));
+
+			/* fsync the data directory to persist the rename() */
+			START_CRIT_SECTION();
+			fsync_fname(".", true);
+			END_CRIT_SECTION();
 		}
 
 		/*
@@ -6522,6 +6540,14 @@ StartupXLOG(void)
 								TABLESPACE_MAP, TABLESPACE_MAP_OLD)));
 		}
 
+		/* fsync the data directory to persist the rename() */
+		if (haveBackupLabel || haveTblspcMap)
+		{
+			START_CRIT_SECTION();
+			fsync_fname(".", true);
+			END_CRIT_SECTION();
+		}
+
 		/* Check that the GUCs used to generate the WAL allow recovery */
 		CheckRequiredParameterValues();
 
@@ -7303,6 +7329,10 @@ StartupXLOG(void)
 						 errmsg("could not rename file \"%s\" to \"%s\": %m",
 								origpath, partialpath)));
 				XLogArchiveNotify(partialfname);
+
+				START_CRIT_SECTION();
+				fsync_fname(XLOGDIR, true);
+				END_CRIT_SECTION();
 			}
 		}
 	}
@@ -10906,6 +10936,11 @@ CancelBackup(void)
 						   BACKUP_LABEL_FILE, BACKUP_LABEL_OLD,
 						   TABLESPACE_MAP, TABLESPACE_MAP_OLD)));
 	}
+
+	/* fsync the data directory to persist the renames */
+	START_CRIT_SECTION();
+	fsync_fname(".", true);
+	END_CRIT_SECTION();
 }
 
 /*
diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index 7af56a9..1219f4b 100644
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -476,6 +476,10 @@ KeepFileRestoredFromArchive(char *path, char *xlogfname)
 				 errmsg("could not rename file \"%s\" to \"%s\": %m",
 						path, xlogfpath)));
 
+	START_CRIT_SECTION();
+	fsync_fname(XLOGDIR, true);
+	END_CRIT_SECTION();
+
 	/*
 	 * Create .done file forcibly to prevent the restored segment from being
 	 * archived again later.
@@ -586,6 +590,10 @@ XLogArchiveForceDone(const char *xlog)
 					 errmsg("could not rename file \"%s\" to \"%s\": %m",
 							archiveReady, archiveDone)));
 
+		START_CRIT_SECTION();
+		fsync_fname(XLOGDIR "/archive_status", true);
+		END_CRIT_SECTION();
+
 		return;
 	}
 
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 4df669e..be59442 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -733,4 +733,8 @@ pgarch_archiveDone(char *xlog)
 				(errcode_for_file_access(),
 				 errmsg("could not rename file \"%s\" to \"%s\": %m",
 						rlogready, rlogdone)));
+
+	START_CRIT_SECTION();
+	fsync_fname(XLOGDIR "/archive_status", true);
+	END_CRIT_SECTION();
 }
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to