You've already forked pg_probackup
mirror of
https://github.com/postgrespro/pg_probackup.git
synced 2026-06-21 01:34:15 +02:00
fix set_forkname
Fork detection were broken before set_forkname extraction, and its bug were copied into. Lets reimplement it to be like `parse_filename_for_nonetemp_relation` in PostgreSQL code.
This commit is contained in:
@@ -1139,7 +1139,18 @@ get_backup_filelist(pgBackup *backup, bool strict)
|
||||
file->uncompressed_size = write_size;
|
||||
|
||||
if (file->external_dir_num == 0)
|
||||
{
|
||||
bool is_datafile = file->is_datafile;
|
||||
set_forkname(file);
|
||||
if (is_datafile != file->is_datafile)
|
||||
{
|
||||
elog(WARNING, "File '%s' was stored as datafile, but looks like it is not",
|
||||
file->rel_path);
|
||||
/* Lets fail in tests */
|
||||
Assert(file->is_datafile == file->is_datafile);
|
||||
file->is_datafile = is_datafile;
|
||||
}
|
||||
}
|
||||
|
||||
parray_append(files, file);
|
||||
}
|
||||
|
||||
@@ -631,20 +631,6 @@ dir_check_file(pgFile *file, bool backup_logs)
|
||||
|
||||
if (file->forkName == ptrack) /* Compatibility with left-overs from ptrack1 */
|
||||
return CHECK_FALSE;
|
||||
else if (file->forkName != none)
|
||||
return CHECK_TRUE;
|
||||
|
||||
/* Set is_datafile flag */
|
||||
{
|
||||
char suffix[MAXFNAMELEN];
|
||||
|
||||
/* check if file is datafile */
|
||||
sscanf_res = sscanf(file->name, "%u.%d.%s", &(file->relOid),
|
||||
&(file->segno), suffix);
|
||||
Assert(sscanf_res > 0); /* since first char is digit */
|
||||
if (sscanf_res == 1 || sscanf_res == 2)
|
||||
file->is_datafile = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1789,34 +1775,74 @@ pfilearray_clear_locks(parray *file_list)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool
|
||||
is_forkname(char *name, size_t *pos, const char *forkname)
|
||||
{
|
||||
size_t fnlen = strlen(forkname);
|
||||
if (strncmp(name + *pos, forkname, fnlen) != 0)
|
||||
return false;
|
||||
*pos += fnlen;
|
||||
return true;
|
||||
}
|
||||
|
||||
#define OIDCHARS 10
|
||||
|
||||
/* Set forkName if possible */
|
||||
void
|
||||
bool
|
||||
set_forkname(pgFile *file)
|
||||
{
|
||||
int name_len = strlen(file->name);
|
||||
size_t i = 0;
|
||||
uint64_t oid = 0; /* use 64bit to not check for overflow in a loop */
|
||||
|
||||
/* Auxiliary fork of the relfile */
|
||||
if (name_len > 3 && strcmp(file->name + name_len - 3, "_vm") == 0)
|
||||
/* pretend it is not relation file */
|
||||
file->relOid = 0;
|
||||
file->forkName = none;
|
||||
file->is_datafile = false;
|
||||
|
||||
for (i = 0; isdigit(file->name[i]); i++)
|
||||
{
|
||||
if (i == 0 && file->name[i] == '0')
|
||||
return false;
|
||||
oid = oid * 10 + file->name[i] - '0';
|
||||
}
|
||||
if (i == 0 || i > OIDCHARS || oid > UINT32_MAX)
|
||||
return false;
|
||||
|
||||
/* usual fork name */
|
||||
/* /^\d+_(vm|fsm|init|ptrack)$/ */
|
||||
if (is_forkname(file->name, &i, "_vm"))
|
||||
file->forkName = vm;
|
||||
|
||||
else if (name_len > 4 && strcmp(file->name + name_len - 4, "_fsm") == 0)
|
||||
else if (is_forkname(file->name, &i, "_fsm"))
|
||||
file->forkName = fsm;
|
||||
|
||||
else if (name_len > 4 && strcmp(file->name + name_len - 4, ".cfm") == 0)
|
||||
file->forkName = cfm;
|
||||
|
||||
else if (name_len > 5 && strcmp(file->name + name_len - 5, "_init") == 0)
|
||||
else if (is_forkname(file->name, &i, "_init"))
|
||||
file->forkName = init;
|
||||
|
||||
else if (name_len > 7 && strcmp(file->name + name_len - 7, "_ptrack") == 0)
|
||||
else if (is_forkname(file->name, &i, "_ptrack"))
|
||||
file->forkName = ptrack;
|
||||
|
||||
// extract relOid for certain forks
|
||||
/* segment number */
|
||||
/* /^\d+(_(vm|fsm|init|ptrack))?\.\d+$/ */
|
||||
if (file->name[i] == '.' && isdigit(file->name[i+1]))
|
||||
{
|
||||
for (i++; isdigit(file->name[i]); i++)
|
||||
;
|
||||
}
|
||||
|
||||
if ((file->forkName == vm ||
|
||||
file->forkName == fsm ||
|
||||
file->forkName == init ||
|
||||
file->forkName == cfm) &&
|
||||
(sscanf(file->name, "%u*", &(file->relOid)) != 1))
|
||||
file->relOid = 0;
|
||||
/* CFS "fork name" */
|
||||
if (file->forkName == none &&
|
||||
is_forkname(file->name, &i, ".cfm"))
|
||||
{
|
||||
/* /^\d+(\.\d+)?.cfm$/ */
|
||||
file->forkName = cfm;
|
||||
}
|
||||
|
||||
/* If there are excess characters, it is not relation file */
|
||||
if (file->name[i] != 0)
|
||||
{
|
||||
file->forkName = none;
|
||||
return false;
|
||||
}
|
||||
|
||||
file->relOid = oid;
|
||||
file->is_datafile = file->forkName == none;
|
||||
return true;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1098,7 +1098,7 @@ extern int pgCompareString(const void *str1, const void *str2);
|
||||
extern int pgPrefixCompareString(const void *str1, const void *str2);
|
||||
extern int pgCompareOid(const void *f1, const void *f2);
|
||||
extern void pfilearray_clear_locks(parray *file_list);
|
||||
extern void set_forkname(pgFile *file);
|
||||
extern bool set_forkname(pgFile *file);
|
||||
|
||||
/* in data.c */
|
||||
extern bool check_data_file(ConnectionArgs *arguments, pgFile *file,
|
||||
|
||||
Reference in New Issue
Block a user