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);