At Thu, 09 Mar 2023 10:58:41 +0900 (JST), I wrote
> behavior for that purpose. I believe it is reasonable to make
> basebackup error-out when it encounters an in-place tablespace
> directory when TABLESPACE_MAP is activated.

It turned out to be not as simple as I thought, though...

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 543d4d897a..c33a51772a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -8241,7 +8241,8 @@ issue_xlog_fsync(int fd, XLogSegNo segno, TimeLineID tli)
  */
 void
 do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
-				   BackupState *state, StringInfo tblspcmapfile)
+				   BackupState *state, StringInfo tblspcmapfile,
+				   bool allow_inplace_tsps)
 {
 	bool		backup_started_in_recovery;
 
@@ -8434,6 +8435,7 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
 			int			rllen;
 			StringInfoData escapedpath;
 			char	   *s;
+			PGFileType  ftype;
 
 			/* Skip anything that doesn't look like a tablespace */
 			if (strspn(de->d_name, "0123456789") != strlen(de->d_name))
@@ -8446,7 +8448,14 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces,
 			 * we sometimes use allow_in_place_tablespaces to create
 			 * directories directly under pg_tblspc, which would fail below.
 			 */
-			if (get_dirent_type(fullpath, de, false, ERROR) != PGFILETYPE_LNK)
+			ftype = get_dirent_type(fullpath, de, false, ERROR);
+
+			/* reject in-place tablespace directories when not allowed */
+			if (ftype == PGFILETYPE_DIR && !allow_inplace_tsps)
+				ereport(ERROR,
+						errmsg("cannot handle in-place tablespace directories when TABLESPACE_MAP is activated"),
+						errhint("If you are using pg_basebackup, try -Fp instead."));
+			if (ftype != PGFILETYPE_LNK)
 				continue;
 
 			rllen = readlink(fullpath, linkpath, sizeof(linkpath));
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index c07daa874f..face85c1bf 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -99,7 +99,8 @@ pg_backup_start(PG_FUNCTION_ARGS)
 	MemoryContextSwitchTo(oldcontext);
 
 	register_persistent_abort_backup_handler();
-	do_pg_backup_start(backupidstr, fast, NULL, backup_state, tablespace_map);
+	do_pg_backup_start(backupidstr, fast, NULL, backup_state, tablespace_map,
+					   true);
 
 	PG_RETURN_LSN(backup_state->startpoint);
 }
diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index 6efdefb591..c69e91a4ff 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -259,8 +259,10 @@ perform_base_backup(basebackup_options *opt, bbsink *sink)
 	tablespace_map = makeStringInfo();
 
 	basebackup_progress_wait_checkpoint();
+
+	/* don't allow in-place tablespace when sending the tablespace map file */
 	do_pg_backup_start(opt->label, opt->fastcheckpoint, &state.tablespaces,
-					   backup_state, tablespace_map);
+					   backup_state, tablespace_map, !opt->sendtblspcmapfile);
 
 	state.startptr = backup_state->startpoint;
 	state.starttli = backup_state->starttli;
diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h
index cfe5409738..0a64a84b71 100644
--- a/src/include/access/xlog.h
+++ b/src/include/access/xlog.h
@@ -280,7 +280,8 @@ typedef enum SessionBackupState
 
 extern void do_pg_backup_start(const char *backupidstr, bool fast,
 							   List **tablespaces, BackupState *state,
-							   StringInfo tblspcmapfile);
+							   StringInfo tblspcmapfile,
+							   bool allow_inplace_tsps);
 extern void do_pg_backup_stop(BackupState *state, bool waitforarchive);
 extern void do_pg_abort_backup(int code, Datum arg);
 extern void register_persistent_abort_backup_handler(void);

Reply via email to