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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers