diff -cr pgsql/src/backend/access/transam/xlog.c pgsql-arcstatdir/src/backend/access/transam/xlog.c *** pgsql/src/backend/access/transam/xlog.c Fri Oct 31 11:04:59 2008 --- pgsql-arcstatdir/src/backend/access/transam/xlog.c Sat Nov 8 17:10:22 2008 *************** *** 438,444 **** XLogRecPtr *minRecoveryLoc); static void rm_redo_error_callback(void *arg); static int get_sync_bit(int method); ! /* * Insert an XLOG record having the specified RMID and info bytes, --- 438,444 ---- XLogRecPtr *minRecoveryLoc); static void rm_redo_error_callback(void *arg); static int get_sync_bit(int method); ! static void ValidateXLOGDirectoryStructure(void); /* * Insert an XLOG record having the specified RMID and info bytes, *************** *** 2825,2830 **** --- 2825,2878 ---- } /* + * The purpose of this procedure is to verify whether pg_xlog and + * pg_xlog/archive_status exist. If the latter does not, it attempts + * to recreate it. It is not the goal of this procedure to verify the + * contents of these directories, but to help in cases where someone + * has performed a cluster copy for PITR purposes but forgot to + * recreate archive_status in pg_xlog. + */ + 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 a pre-existing directory */ + 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)) + return; /* Directory structure looks good */ + else + ereport(FATAL, + (errmsg("required WAL directory \"%s\" does not exist", path), + errhint("Expected \"%s\" to be a directory.", path))); + } + else + { + ereport(LOG, + (errmsg("recreating missing WAL directory \"%s\"", path))); + + if (mkdir(path, 0700) < 0) + { + ereport(FATAL, + (errmsg("could not create missing directory \"%s\"", + path))); + } + } + } + + /* * Remove previous backup history files. This also retries creation of * .ready files for any backup history files for which XLogArchiveNotify * failed earlier. *************** *** 4879,4884 **** --- 4927,4939 ---- #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. */