Archived redo logs / Managed recovery mode?

Started by Matthew Kirkwoodover 24 years ago1 messages
#1Matthew Kirkwood
matthew@hairy.beasts.org
1 attachment(s)

Hi,

Firstly, the attached patch implements archiving of off-
line redo logs, via the wal_archive_dir GUC option. It
builds and appears to work (though it looks like guc-file.l
has some problems with unquoted strings containing slashes).

TODO: handle EXDEV from link/rename, and copy rather
than renaming.

Clearly this isn't a lot of use at the moment, but what I'd
really like would be a way to implement what our (Oracle)
DBA calls "managed recovery".

Essentially, the standby database is opened in read-only
mode (since PG seems to lack this, having it not open at
all should suffice :). and archived redo logs are copied
over from the live database (we do it via rsync, every 5
minutes) and rolled forward.

(Note: for what it's worth, we're using this because
Oracle's Advanced Replication is too unstable.)

Is there an easy way to do this? I suppose that while
there isn't a readonly option, it might be best done with
an external tool, not unlike resetxlog.

What are the plans for replication in 7.2 (assuming that
is what's next)? The rserv stuff looks neat, but rather
intricate. A cheap, out-of-band replication system would
make me very happy.

Matthew.

Attachments:

pg-archive.difftext/plain; charset=US-ASCII; name=pg-archive.diffDownload
Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.65
diff -u -r1.65 xlog.c
--- src/backend/access/transam/xlog.c	2001/04/05 16:55:21	1.65
+++ src/backend/access/transam/xlog.c	2001/04/27 14:49:44
@@ -97,7 +97,7 @@
 int			XLOG_DEBUG = 0;
 char	   *XLOG_sync_method = NULL;
 const char	XLOG_sync_method_default[] = DEFAULT_SYNC_METHOD_STR;
-char		XLOG_archive_dir[MAXPGPATH];		/* null string means
+char		*XLOG_archive_dir = NULL;			/* null string means
 												 * delete 'em */
 
 /* these are derived from XLOG_sync_method by assign_xlog_sync_method */
@@ -1476,9 +1476,7 @@
 	DIR		   *xldir;
 	struct dirent *xlde;
 	char		lastoff[32];
-	char		path[MAXPGPATH];
-
-	Assert(XLOG_archive_dir[0] == 0);	/* ! implemented yet */
+	char		path[MAXPGPATH], arcpath[MAXPGPATH];
 
 	xldir = opendir(XLogDir);
 	if (xldir == NULL)
@@ -1493,11 +1491,25 @@
 			strspn(xlde->d_name, "0123456789ABCDEF") == 16 &&
 			strcmp(xlde->d_name, lastoff) <= 0)
 		{
-			elog(LOG, "MoveOfflineLogs: %s %s", (XLOG_archive_dir[0]) ?
+			elog(LOG, "MoveOfflineLogs: %s %s", XLOG_archive_dir ?
 				 "archive" : "remove", xlde->d_name);
 			sprintf(path, "%s%c%s", XLogDir, SEP_CHAR, xlde->d_name);
-			if (XLOG_archive_dir[0] == 0)
+			if (XLOG_archive_dir == NULL)
 				unlink(path);
+			else {
+				sprintf(arcpath, "%s%c%s", XLOG_archive_dir, SEP_CHAR, xlde->d_name);
+#ifndef	__BEOS__
+				if (link(path, arcpath) < 0)
+					elog(STOP, "MoveOfflineLogs: %s => %s failed: %m",
+								path, arcpath);
+				else
+					unlink(path);
+#else
+				if (rename(path, arcpath) < 0)
+					elog(STOP, "MoveOfflineLogs: %s => %s failed: %m",
+								path, arcpath);
+#endif
+			}
 		}
 		errno = 0;
 	}
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.35
diff -u -r1.35 guc.c
--- src/backend/utils/misc/guc.c	2001/03/22 17:41:47	1.35
+++ src/backend/utils/misc/guc.c	2001/04/27 14:49:48
@@ -13,6 +13,9 @@
 
 #include "postgres.h"
 
+#include <sys/types.h>
+#include <sys/stat.h>
+
 #include <errno.h>
 #include <float.h>
 #include <limits.h>
@@ -41,6 +44,8 @@
 extern int	CommitSiblings;
 extern bool FixBTree;
 
+static bool check_dirname(const char *dirname);
+
 #ifdef ENABLE_SYSLOG
 extern char *Syslog_facility;
 extern char *Syslog_ident;
@@ -351,6 +356,9 @@
 		XLOG_sync_method_default,
 	check_xlog_sync_method, assign_xlog_sync_method},
 
+	{"wal_archive_dir", PGC_SUSET, &XLOG_archive_dir,
+	"", check_dirname, NULL},
+
 	{NULL, 0, NULL, NULL, NULL, NULL}
 };
 
@@ -869,6 +877,17 @@
 			*cp = '_';
 }
 
+
+static bool
+check_dirname(const char *dirname)
+{
+	struct stat st;
+	if (stat(dirname, &st) < 0)
+		return false;
+	if (!S_ISDIR(st.st_mode))
+		return false;
+	return true;
+}
 
 
 #ifdef ENABLE_SYSLOG
Index: src/include/access/xlog.h
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/include/access/xlog.h,v
retrieving revision 1.23
diff -u -r1.23 xlog.h
--- src/include/access/xlog.h	2001/03/22 04:00:32	1.23
+++ src/include/access/xlog.h	2001/04/27 14:49:48
@@ -184,6 +184,7 @@
 extern int	XLOG_DEBUG;
 extern char *XLOG_sync_method;
 extern const char XLOG_sync_method_default[];
+extern char *XLOG_archive_dir;
 
 
 extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata);