mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
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
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.120 2008/07/18 17:33:17 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.121 2008/11/09 17:51:15 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="backup">
|
<chapter id="backup">
|
||||||
<title>Backup and Restore</title>
|
<title>Backup and Restore</title>
|
||||||
@ -945,8 +945,6 @@ SELECT pg_stop_backup();
|
|||||||
If you didn't archive <filename>pg_xlog/</> at all, then recreate it,
|
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
|
being careful to ensure that you re-establish it as a symbolic link
|
||||||
if you had it set up that way before.
|
if you had it set up that way before.
|
||||||
Be sure to recreate the subdirectory
|
|
||||||
<filename>pg_xlog/archive_status/</> as well.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.321 2008/10/31 15:04:59 heikki Exp $
|
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.322 2008/11/09 17:51:15 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -416,6 +416,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
|
|||||||
const char *recovername, off_t expectedSize);
|
const char *recovername, off_t expectedSize);
|
||||||
static void PreallocXlogFiles(XLogRecPtr endptr);
|
static void PreallocXlogFiles(XLogRecPtr endptr);
|
||||||
static void RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr);
|
static void RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr);
|
||||||
|
static void ValidateXLOGDirectoryStructure(void);
|
||||||
static void CleanupBackupHistory(void);
|
static void CleanupBackupHistory(void);
|
||||||
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode);
|
static XLogRecord *ReadRecord(XLogRecPtr *RecPtr, int emode);
|
||||||
static bool ValidXLOGHeader(XLogPageHeader hdr, int emode);
|
static bool ValidXLOGHeader(XLogPageHeader hdr, int emode);
|
||||||
@ -2824,6 +2825,53 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
|
|||||||
FreeDir(xldir);
|
FreeDir(xldir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
* Remove previous backup history files. This also retries creation of
|
||||||
* .ready files for any backup history files for which XLogArchiveNotify
|
* .ready files for any backup history files for which XLogArchiveNotify
|
||||||
@ -4878,6 +4926,13 @@ StartupXLOG(void)
|
|||||||
pg_usleep(60000000L);
|
pg_usleep(60000000L);
|
||||||
#endif
|
#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
|
* Initialize on the assumption we want to recover to the same timeline
|
||||||
* that's active according to pg_control.
|
* that's active according to pg_control.
|
||||||
|
Reference in New Issue
Block a user