Hi All,

I tried performing pg_basebackup after creating a symbolic link for
pg_replslot, pg_stat_tmp, pg_log and pg_clog in the source directory and
found that on the backup location pg_stat_tmp, pg_repl_slot is a corrupt
file rather than a link or directory whereas pg_clog and pg_log are getting
skipped. As per the documentation of pg_basebackup, symbolic links on any
directories
other than tablespace and xlog should be skipped. But this statement is not
true for pg_replslot and pg_stat_tmp. The reason is as follows:

pg_basebackup is expecting pg_stat_tmp/pg_replslot to be a directory and
irrespective of  whether pg_stat_tmp is empty or not, it will always
include it as a empty directory in backup path. Now, in my case i have
created a softlink for pg_stat_tmp/pg_replslot and pg_basebackup is trying
to create a tar format header without changing the filemode as it does in
case of pg_xlog. Also, linkpath is not considered as in case of pg_tblspc.
This is the reason why a regular file is getting created in the backup path
even though i have a symbolic link in the source path but ideally it should
be skipped.

*Solution:* Skip pg_stat_tmp and pg_replslot if they are symbolic link.
Attached is the patch that fix this issue.

With Regards,
Ashutosh Sharma
EnterpriseDB: *http://www.enterprisedb.com <http://www.enterprisedb.com>*
diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c
index 1008873..5163b85 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -970,9 +970,25 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
 		  strncmp(de->d_name, PG_STAT_TMP_DIR, strlen(PG_STAT_TMP_DIR)) == 0)
 		{
 			if (!sizeonly)
-				_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
-			size += 512;
-			continue;
+			{
+				/* If pg_stat_tmp is a symlink, skip it */
+#ifndef WIN32
+				if (S_ISLNK(statbuf.st_mode))
+#else
+				if (pgwin32_is_junction(pathbuf))
+#endif
+				{
+					ereport(WARNING,
+						(errmsg("skipping special file \"%s\"", pathbuf)));
+					continue;
+				}
+				else
+				{
+					_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
+					size += 512;
+					continue;
+				}
+			}
 		}
 
 		/*
@@ -982,9 +998,25 @@ sendDir(char *path, int basepathlen, bool sizeonly, List *tablespaces,
 		if (strcmp(de->d_name, "pg_replslot") == 0)
 		{
 			if (!sizeonly)
-				_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
-			size += 512;		/* Size of the header just added */
-			continue;
+			{
+				/* If pg_replslot is a symlink, skip it */
+#ifndef WIN32
+				if (S_ISLNK(statbuf.st_mode))
+#else
+				if (pgwin32_is_junction(pathbuf))
+#endif
+				{
+					ereport(WARNING,
+						(errmsg("skipping special file \"%s\"", pathbuf)));
+					continue;
+				}
+				else
+				{
+					_tarWriteHeader(pathbuf + basepathlen + 1, NULL, &statbuf);
+					size += 512;		/* Size of the header just added */
+					continue;
+				}
+			}
 		}
 
 		/*
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to