diff options
author | Tom Lane | 2008-11-09 17:51:15 +0000 |
---|---|---|
committer | Tom Lane | 2008-11-09 17:51:15 +0000 |
commit | 3e69723c18da1eb95b631dd42632a4241edb5c97 (patch) | |
tree | 92103bf7c9eabf7c764d7248eaea70590726bb11 | |
parent | 2793649040fb2bd04c3e50c21c139fc1834f3da9 (diff) |
Add a startup check that pg_xlog and pg_xlog/archive_status exist.
If the latter doesn't exist, automatically recreate it. (We don't do
this for pg_xlog, though, per discussion.)
Jonah Harris
-rw-r--r-- | doc/src/sgml/backup.sgml | 2 | ||||
-rw-r--r-- | src/backend/access/transam/xlog.c | 55 |
2 files changed, 55 insertions, 2 deletions
diff --git a/doc/src/sgml/backup.sgml b/doc/src/sgml/backup.sgml index c3fe9e76f2..f04d487251 100644 --- a/doc/src/sgml/backup.sgml +++ b/doc/src/sgml/backup.sgml @@ -945,8 +945,6 @@ SELECT pg_stop_backup(); If you didn't archive <filename>pg_xlog/</> at all, then recreate it, being careful to ensure that you re-establish it as a symbolic link if you had it set up that way before. - Be sure to recreate the subdirectory - <filename>pg_xlog/archive_status/</> as well. </para> </listitem> <listitem> diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 003098f3b3..0eeff6f7db 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -416,6 +416,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname, const char *recovername, off_t expectedSize); static void PreallocXlogFiles(XLogRecPtr endptr); static void RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr); +static void ValidateXLOGDirectoryStructure(void); static void CleanupBackupHistory(void); static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode); static bool ValidXLOGHeader(XLogPageHeader hdr, int emode); @@ -2825,6 +2826,53 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr) } /* + * Verify whether pg_xlog and pg_xlog/archive_status exist. + * If the latter does not exist, recreate it. + * + * It is not the goal of this function to verify the contents of these + * directories, but to help in cases where someone has performed a cluster + * copy for PITR purposes but omitted pg_xlog from the copy. + * + * We could also recreate pg_xlog if it doesn't exist, but a deliberate + * policy decision was made not to. It is fairly common for pg_xlog to be + * a symlink, and if that was the DBA's intent then automatically making a + * plain directory would result in degraded performance with no notice. + */ +static void +ValidateXLOGDirectoryStructure(void) +{ + char path[MAXPGPATH]; + struct stat stat_buf; + + /* Check for pg_xlog; if it doesn't exist, error out */ + if (stat(XLOGDIR, &stat_buf) != 0 || + !S_ISDIR(stat_buf.st_mode)) + ereport(FATAL, + (errmsg("required WAL directory \"%s\" does not exist", + XLOGDIR))); + + /* Check for archive_status */ + snprintf(path, MAXPGPATH, XLOGDIR "/archive_status"); + if (stat(path, &stat_buf) == 0) + { + /* Check for weird cases where it exists but isn't a directory */ + if (!S_ISDIR(stat_buf.st_mode)) + ereport(FATAL, + (errmsg("required WAL directory \"%s\" does not exist", + path))); + } + else + { + ereport(LOG, + (errmsg("creating missing WAL directory \"%s\"", path))); + if (mkdir(path, 0700) < 0) + ereport(FATAL, + (errmsg("could not create missing directory \"%s\": %m", + path))); + } +} + +/* * Remove previous backup history files. This also retries creation of * .ready files for any backup history files for which XLogArchiveNotify * failed earlier. @@ -4879,6 +4927,13 @@ StartupXLOG(void) #endif /* + * Verify that pg_xlog and pg_xlog/archive_status exist. In cases where + * someone has performed a copy for PITR, these directories may have + * been excluded and need to be re-created. + */ + ValidateXLOGDirectoryStructure(); + + /* * Initialize on the assumption we want to recover to the same timeline * that's active according to pg_control. */ |