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