|
7 | 7 | * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
|
8 | 8 | * Portions Copyright (c) 1994, Regents of the University of California
|
9 | 9 | *
|
10 |
| - * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.321 2008/10/31 15:04:59 heikki Exp $ |
| 10 | + * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.322 2008/11/09 17:51:15 tgl Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
@@ -416,6 +416,7 @@ static bool RestoreArchivedFile(char *path, const char *xlogfname,
|
416 | 416 | constchar*recovername,off_texpectedSize);
|
417 | 417 | staticvoidPreallocXlogFiles(XLogRecPtrendptr);
|
418 | 418 | staticvoidRemoveOldXlogFiles(uint32log,uint32seg,XLogRecPtrendptr);
|
| 419 | +staticvoidValidateXLOGDirectoryStructure(void); |
419 | 420 | staticvoidCleanupBackupHistory(void);
|
420 | 421 | staticXLogRecord*ReadRecord(XLogRecPtr*RecPtr,intemode);
|
421 | 422 | staticboolValidXLOGHeader(XLogPageHeaderhdr,intemode);
|
@@ -2824,6 +2825,53 @@ RemoveOldXlogFiles(uint32 log, uint32 seg, XLogRecPtr endptr)
|
2824 | 2825 | FreeDir(xldir);
|
2825 | 2826 | }
|
2826 | 2827 |
|
| 2828 | +/* |
| 2829 | + * Verify whether pg_xlog and pg_xlog/archive_status exist. |
| 2830 | + * If the latter does not exist, recreate it. |
| 2831 | + * |
| 2832 | + * It is not the goal of this function to verify the contents of these |
| 2833 | + * directories, but to help in cases where someone has performed a cluster |
| 2834 | + * copy for PITR purposes but omitted pg_xlog from the copy. |
| 2835 | + * |
| 2836 | + * We could also recreate pg_xlog if it doesn't exist, but a deliberate |
| 2837 | + * policy decision was made not to. It is fairly common for pg_xlog to be |
| 2838 | + * a symlink, and if that was the DBA's intent then automatically making a |
| 2839 | + * plain directory would result in degraded performance with no notice. |
| 2840 | + */ |
| 2841 | +staticvoid |
| 2842 | +ValidateXLOGDirectoryStructure(void) |
| 2843 | +{ |
| 2844 | +charpath[MAXPGPATH]; |
| 2845 | +structstatstat_buf; |
| 2846 | + |
| 2847 | +/* Check for pg_xlog; if it doesn't exist, error out */ |
| 2848 | +if (stat(XLOGDIR,&stat_buf)!=0|| |
| 2849 | +!S_ISDIR(stat_buf.st_mode)) |
| 2850 | +ereport(FATAL, |
| 2851 | +(errmsg("required WAL directory \"%s\" does not exist", |
| 2852 | +XLOGDIR))); |
| 2853 | + |
| 2854 | +/* Check for archive_status */ |
| 2855 | +snprintf(path,MAXPGPATH,XLOGDIR"/archive_status"); |
| 2856 | +if (stat(path,&stat_buf)==0) |
| 2857 | +{ |
| 2858 | +/* Check for weird cases where it exists but isn't a directory */ |
| 2859 | +if (!S_ISDIR(stat_buf.st_mode)) |
| 2860 | +ereport(FATAL, |
| 2861 | +(errmsg("required WAL directory \"%s\" does not exist", |
| 2862 | +path))); |
| 2863 | +} |
| 2864 | +else |
| 2865 | +{ |
| 2866 | +ereport(LOG, |
| 2867 | +(errmsg("creating missing WAL directory \"%s\"",path))); |
| 2868 | +if (mkdir(path,0700)<0) |
| 2869 | +ereport(FATAL, |
| 2870 | +(errmsg("could not create missing directory \"%s\": %m", |
| 2871 | +path))); |
| 2872 | +} |
| 2873 | +} |
| 2874 | + |
2827 | 2875 | /*
|
2828 | 2876 | * Remove previous backup history files. This also retries creation of
|
2829 | 2877 | * .ready files for any backup history files for which XLogArchiveNotify
|
@@ -4878,6 +4926,13 @@ StartupXLOG(void)
|
4878 | 4926 | pg_usleep(60000000L);
|
4879 | 4927 | #endif
|
4880 | 4928 |
|
| 4929 | +/* |
| 4930 | + * Verify that pg_xlog and pg_xlog/archive_status exist. In cases where |
| 4931 | + * someone has performed a copy for PITR, these directories may have |
| 4932 | + * been excluded and need to be re-created. |
| 4933 | + */ |
| 4934 | +ValidateXLOGDirectoryStructure(); |
| 4935 | + |
4881 | 4936 | /*
|
4882 | 4937 | * Initialize on the assumption we want to recover to the same timeline
|
4883 | 4938 | * that's active according to pg_control.
|
|