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