8000 Fix handling recursive tablespaces. · postgrespro/pg_probackup@9e8d70d · GitHub
[go: up one dir, main page]

Skip to content

Commit 9e8d70d

Browse files
committed
Fix handling recursive tablespaces.
Earlier it was disabled to have recursive tablespaces. The code was buggy, so fix the code and allow to have such tablespaces.
1 parent 98c6719 commit 9e8d70d

File tree

1 file changed

+60
-46
lines changed

1 file changed

+60
-46
lines changed

src/dir.c

Lines changed: 60 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ typedef struct TablespaceCreatedList
118118

119119
static int BlackListCompare(const void *str1, const void *str2);
120120

121-
static bool dir_check_file(const char *root, pgFile *file);
121+
static char dir_check_file(const char *root, pgFile *file);
122122
static void dir_list_file_internal(parray *files, const char *root,
123123
pgFile *parent, bool exclude,
124124
bool omit_symlink, parray *black_list);
@@ -448,6 +448,10 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
448448
pgFileFree(file);
449449
}
450450

451+
#define CHECK_FALSE 0
452+
#define CHECK_TRUE 1
453+
#define CHECK_EXCLUDE_FALSE 2
454+
451455
/*
452456
* Check file or directory.
453457
*
@@ -456,16 +460,21 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
456460
* Skip files:
457461
* - skip temp tables files
458462
* - skip unlogged tables files
463+
* Skip recursive tablespace content
459464
* Set flags for:
460465
* - database directories
461466
* - datafiles
462467
*/
463-
static bool
468+
static char
464469
dir_check_file(const char *root, pgFile *file)
465470
{
466471
const char *rel_path;
467472
int i;
468473
int sscanf_res;
474+
bool in_tablespace = false;
475+
476+
rel_path = GetRelativePath(file->path, root);
477+
in_tablespace = path_is_prefix_of_path(PG_TBLSPC_DIR, rel_path);
469478

470479
/* Check if we need to exclude file by name */
471480
if (S_IS 8000 REG(file->mode))
@@ -478,7 +487,7 @@ dir_check_file(const char *root, pgFile *file)
478487
{
479488
/* Skip */
480489
elog(VERBOSE, "Excluding file: %s", file->name);
481-
return false;
490+
return CHECK_FALSE;
482491
}
483492
}
484493

@@ -487,14 +496,14 @@ dir_check_file(const char *root, pgFile *file)
487496
{
488497
/* Skip */
489498
elog(VERBOSE, "Excluding file: %s", file->name);
490-
return false;
499+
return CHECK_FALSE;
491500
}
492501
}
493502
/*
494503
* If the directory name is in the exclude list, do not list the
495504
* contents.
496505
*/
497-
else if (S_ISDIR(file->mode))
506+
else if (S_ISDIR(file->mode) && !in_tablespace)
498507
{
499508
/*
500509
* If the item in the exclude list starts with '/', compare to
@@ -510,20 +519,18 @@ dir_check_file(const char *root, pgFile *file)
510519
{
511520
elog(VERBOSE, "Excluding directory content: %s",
512521
file->name);
513-
return false;
522+
return CHECK_EXCLUDE_FALSE;
514523
}
515524
}
516525
else if (strcmp(file->name, pgdata_exclude_dir[i]) == 0)
517526
{
518527
elog(VERBOSE, "Excluding directory content: %s",
519528
file->name);
520-
return false;
529+
return CHECK_EXCLUDE_FALSE;
521530
}
522531
}
523532
}
524533

525-
rel_path = GetRelativePath(file->path, root);
526-
527534
/*
528535
* Do not copy tablespaces twice. It may happen if the tablespace is located
529536
* inside the PGDATA.
@@ -539,14 +546,33 @@ dir_check_file(const char *root, pgFile *file)
539546
* pg_tblspc/tblsOid/TABLESPACE_VERSION_DIRECTORY
540547
*/
541548
if (!path_is_prefix_of_path(PG_TBLSPC_DIR, rel_path))
542-
return false;
549+
return CHECK_FALSE;
543550
sscanf_res = sscanf(rel_path, PG_TBLSPC_DIR "/%u/%s",
544551
&tblspcOid, tmp_rel_path);
545552
if (sscanf_res == 0)
546-
return false;
553+
return CHECK_FALSE;
547554
}
548555

549-
if (path_is_prefix_of_path("global", rel_path))
556+
if (in_tablespace)
557+
{
558+
char tmp_rel_path[MAXPGPATH];
559< A3E2 /td>+
560+
sscanf_res = sscanf(rel_path, PG_TBLSPC_DIR "/%u/%[^/]/%u/",
561+
&(file->tblspcOid), tmp_rel_path,
562+
&(file->dbOid));
563+
564+
/*
565+
* We should skip other files and directories rather than
566+
* TABLESPACE_VERSION_DIRECTORY, if this is recursive tablespace.
567+
*/
568+
if (sscanf_res == 2 && strcmp(tmp_rel_path, TABLESPACE_VERSION_DIRECTORY) != 0)
569+
return CHECK_FALSE;
570+
571+
if (sscanf_res == 3 && S_ISDIR(file->mode) &&
572+
strcmp(tmp_rel_path, TABLESPACE_VERSION_DIRECTORY) == 0)
573+
file->is_database = true;
574+
}
575+
else if (path_is_prefix_of_path("global", rel_path))
550576
{
551577
file->tblspcOid = GLOBALTABLESPACE_OID;
552578

@@ -562,22 +588,10 @@ dir_check_file(const char *root, pgFile *file)
562588
if (S_ISDIR(file->mode) && strcmp(file->name, "base") != 0)
563589
file->is_database = true;
564590
}
565-
else if (path_is_prefix_of_path(PG_TBLSPC_DIR, rel_path))
566-
{
567-
char tmp_rel_path[MAXPGPATH];
568-
569-
sscanf_res = sscanf(rel_path, PG_TBLSPC_DIR "/%u/%[^/]/%u/",
570-
&(file->tblspcOid), tmp_rel_path,
571-
&(file->dbOid));
572-
573-
if (sscanf_res == 3 && S_ISDIR(file->mode) &&
574-
strcmp(tmp_rel_path, TABLESPACE_VERSION_DIRECTORY) == 0)
575-
file->is_database = true;
576-
}
577591

578592
/* Do not backup ptrack_init files */
579593
if (S_ISREG(file->mode) && strcmp(file->name, "ptrack_init") == 0)
580-
return false;
594+
return CHECK_FALSE;
581595

582596
/*
583597
* Check files located inside database directories including directory
@@ -587,10 +601,10 @@ dir_check_file(const char *root, pgFile *file)
587601
file->name && file->name[0])
588602
{
589603
if (strcmp(file->name, "pg_internal.init") == 0)
590-
return false;
604+
return CHECK_FALSE;
591605
/* Do not backup temp files */
592606
else if (file->name[0] == 't' && isdigit(file->name[1]))
593-
return false;
607+
return CHECK_FALSE;
594608
else if (isdigit(file->name[0]))
595609
{
596610
char *fork_name;
@@ -605,14 +619,14 @@ dir_check_file(const char *root, pgFile *file)
605619

606620
/* Do not backup ptrack files */
607621
if (strcmp(file->forkName, "ptrack") == 0)
608-
return false;
622+
return CHECK_FALSE;
609623
}
610624
else
611625
{
612626
len = strlen(file->name);
613627
/* reloid.cfm */
614628
if (len > 3 && strcmp(file->name + len - 3, "cfm") == 0)
615-
return true;
629+
return CHECK_TRUE;
616630

617631
sscanf_res = sscanf(file->name, "%u.%d.%s", &(file->relOid),
618632
&(file->segno), suffix);
@@ -624,7 +638,7 @@ dir_check_file(const char *root, pgFile *file)
624638
}
625639
}
626640

627-
return true;
641+
return CHECK_TRUE;
628642
}
629643

630644
/*
@@ -659,6 +673,7 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
659673
{
660674
pgFile *file;
661675
char child[MAXPGPATH];
676+
char check_res;
662677

663678
join_path_components(child, parent->path, dent->d_name);
664679

@@ -694,21 +709,24 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
694709
continue;
695710
}
696711

697-
/* We add the directory anyway */
698-
if (S_ISDIR(file->mode))
699-
parray_append(files, file);
700-
701-
if (exclude && !dir_check_file(root, file))
712+
if (exclude)
702713
{
703-
if (S_ISREG(file->mode))
714+
check_res = dir_check_file(root, file);
715+
if (check_res == CHECK_FALSE)
716+
{
717+
/* Skip */
704718
pgFileFree(file);
705-
/* Skip */
706-
continue;
719+
continue;
720+
}
721+
else if (check_res == CHECK_EXCLUDE_FALSE)
722+
{
723+
/* We add the directory itself which content was excluded */
724+
parray_append(files, file);
725+
continue;
726+
}
707727
}
708728

709-
/* At least add the file */
710-
if (S_ISREG(file->mode))
711-
parray_append(files, file);
729+
parray_append(files, file);
712730

713731
/*
714732
* If the entry is a directory call dir_list_file_internal()
@@ -1219,11 +1237,7 @@ print_file_list(FILE *out, const parray *files, const char *root)
12191237
if (file->is_datafile)
12201238
fprintf(out, ",\"segno\":\"%d\"", file->segno);
12211239

1222-
#ifndef WIN32
1223-
if (S_ISLNK(file->mode))
1224-
#else
1225-
if (pgwin32_is_junction(file->path))
1226-
#endif
1240+
if (file->linked)
12271241
fprintf(out, ",\"linked\":\"%s\"", file->linked);
12281242

12291243
if (file->n_blocks != BLOCKNUM_INVALID)

0 commit comments

Comments
 (0)
0