Skip to content

Commit 8063652

Browse files
committed
Merge branch 'master' into pgpro-1918
2 parents d557b40 + abf646d commit 8063652

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1300
-821
lines changed

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ Regardless of the chosen backup type, all backups taken with `pg_probackup` supp
3939
`pg_probackup` currently has the following limitations:
4040
* Creating backups from a remote server is currently not supported.
4141
* The server from which the backup was taken and the restored server must be compatible by the [block_size](https://postgrespro.com/docs/postgresql/current/runtime-config-preset#GUC-BLOCK-SIZE) and [wal_block_size](https://postgrespro.com/docs/postgresql/current/runtime-config-preset#GUC-WAL-BLOCK-SIZE) parameters and have the same major release number.
42-
* Microsoft Windows operating system is not supported.
42+
* Microsoft Windows operating system support is in beta stage.
4343
* Configuration files outside of PostgreSQL data directory are not included into the backup and should be backed up separately.
4444

4545
## Installation and Setup
@@ -71,13 +71,28 @@ yum install pg_probackup-{11,10,9.6,9.5}
7171
yumdownloader --source pg_probackup-{11,10,9.6,9.5}
7272
```
7373

74+
Once you have `pg_probackup` installed, complete [the setup](https://postgrespro.com/docs/postgrespro/current/app-pgprobackup.html#pg-probackup-install-and-setup).
75+
76+
## Building from source
77+
### Linux
78+
7479
To compile `pg_probackup`, you must have a PostgreSQL installation and raw source tree. To install `pg_probackup`, execute this in the module's directory:
7580

7681
```shell
7782
make USE_PGXS=1 PG_CONFIG=<path_to_pg_config> top_srcdir=<path_to_PostgreSQL_source_tree>
7883
```
84+
### Windows
7985

80-
Once you have `pg_probackup` installed, complete [the setup](https://postgrespro.com/docs/postgrespro/current/app-pgprobackup.html#pg-probackup-install-and-setup).
86+
Currently pg_probackup can be build using only MSVC 2013.
87+
Build PostgreSQL using [pgwininstall](https://github.com/postgrespro/pgwininstall) or [PostgreSQL instruction](https://www.postgresql.org/docs/10/install-windows-full.html) with MSVC 2013.
88+
If zlib support is needed, src/tools/msvc/config.pl must contain path to directory with compiled zlib. [Example](https://gist.githubusercontent.com/gsmol/80989f976ce9584824ae3b1bfb00bd87/raw/240032950d4ac4801a79625dd00c8f5d4ed1180c/gistfile1.txt)
89+
90+
```shell
91+
CALL "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall" amd64
92+
SET PATH=%PATH%;C:\Perl64\bin
93+
SET PATH=%PATH%;C:\msys64\usr\bin
94+
gen_probackup_project.pl C:\path_to_postgresql_source_tree
95+
```
8196

8297
## Documentation
8398

src/backup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2213,9 +2213,9 @@ backup_files(void *arg)
22132213
struct stat buf;
22142214
pgFile *file = (pgFile *) parray_get(arguments->files_list, i);
22152215

2216-
elog(VERBOSE, "Copying file: \"%s\" ", file->path);
22172216
if (!pg_atomic_test_set_flag(&file->lock))
22182217
continue;
2218+
elog(VERBOSE, "Copying file: \"%s\" ", file->path);
22192219

22202220
/* check for interrupt */
22212221
if (interrupted)

src/delete.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -294,15 +294,7 @@ delete_backup_files(pgBackup *backup)
294294
elog(INFO, "Progress: (%zd/%zd). Process file \"%s\"",
295295
i + 1, num_files, file->path);
296296

297-
if (remove(file->path))
298-
{
299-
if (errno == ENOENT)
300-
elog(VERBOSE, "File \"%s\" is absent", file->path);
301-
else
302-
elog(ERROR, "Cannot remove \"%s\": %s", file->path,
303-
strerror(errno));
304-
return;
305-
}
297+
pgFileDelete(file);
306298
}
307299

308300
parray_walk(files, pgFileFree);

src/dir.c

Lines changed: 69 additions & 47 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);
@@ -415,6 +415,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
415415

416416
while (fgets(buf, lengthof(buf), black_list_file) != NULL)
417417
{
418+
black_item[0] = '\0';
418419
join_path_components(black_item, instance_config.pgdata, buf);
419420

420421
if (black_item[strlen(black_item) - 1] == '\n')
@@ -423,7 +424,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
423424
if (black_item[0] == '#' || black_item[0] == '\0')
424425
continue;
425426

426-
parray_append(black_list, black_item);
427+
parray_append(black_list, pgut_strdup(black_item));
427428
}
428429

429430
fclose(black_list_file);
@@ -446,8 +447,18 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
446447

447448
if (!add_root)
448449
pgFileFree(file);
450+
451+
if (black_list)
452+
{
453+
parray_walk(black_list, pfree);
454+
parray_free(black_list);
455+
}
449456
}
450457

458+
#define CHECK_FALSE 0
459+
#define CHECK_TRUE 1
460+
#define CHECK_EXCLUDE_FALSE 2
461+
451462
/*
452463
* Check file or directory.
453464
*
@@ -456,16 +467,21 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
456467
* Skip files:
457468
* - skip temp tables files
458469
* - skip unlogged tables files
470+
* Skip recursive tablespace content
459471
* Set flags for:
460472
* - database directories
461473
* - datafiles
462474
*/
463-
static bool
475+
static char
464476
dir_check_file(const char *root, pgFile *file)
465477
{
466478
const char *rel_path;
467479
int i;
468480
int sscanf_res;
481+
bool in_tablespace = false;
482+
483+
rel_path = GetRelativePath(file->path, root);
484+
in_tablespace = path_is_prefix_of_path(PG_TBLSPC_DIR, rel_path);
469485

470486
/* Check if we need to exclude file by name */
471487
if (S_ISREG(file->mode))
@@ -478,7 +494,7 @@ dir_check_file(const char *root, pgFile *file)
478494
{
479495
/* Skip */
480496
elog(VERBOSE, "Excluding file: %s", file->name);
481-
return false;
497+
return CHECK_FALSE;
482498
}
483499
}
484500

@@ -487,14 +503,14 @@ dir_check_file(const char *root, pgFile *file)
487503
{
488504
/* Skip */
489505
elog(VERBOSE, "Excluding file: %s", file->name);
490-
return false;
506+
return CHECK_FALSE;
491507
}
492508
}
493509
/*
494510
* If the directory name is in the exclude list, do not list the
495511
* contents.
496512
*/
497-
else if (S_ISDIR(file->mode))
513+
else if (S_ISDIR(file->mode) && !in_tablespace)
498514
{
499515
/*
500516
* If the item in the exclude list starts with '/', compare to
@@ -510,20 +526,18 @@ dir_check_file(const char *root, pgFile *file)
510526
{
511527
elog(VERBOSE, "Excluding directory content: %s",
512528
file->name);
513-
return false;
529+
return CHECK_EXCLUDE_FALSE;
514530
}
515531
}
516532
else if (strcmp(file->name, pgdata_exclude_dir[i]) == 0)
517533
{
518534
elog(VERBOSE, "Excluding directory content: %s",
519535
file->name);
520-
return false;
536+
return CHECK_EXCLUDE_FALSE;
521537
}
522538
}
523539
}
524540

525-
rel_path = GetRelativePath(file->path, root);
526-
527541
/*
528542
* Do not copy tablespaces twice. It may happen if the tablespace is located
529543
* inside the PGDATA.
@@ -539,14 +553,33 @@ dir_check_file(const char *root, pgFile *file)
539553
* pg_tblspc/tblsOid/TABLESPACE_VERSION_DIRECTORY
540554
*/
541555
if (!path_is_prefix_of_path(PG_TBLSPC_DIR, rel_path))
542-
return false;
556+
return CHECK_FALSE;
543557
sscanf_res = sscanf(rel_path, PG_TBLSPC_DIR "/%u/%s",
544558
&tblspcOid, tmp_rel_path);
545559
if (sscanf_res == 0)
546-
return false;
560+
return CHECK_FALSE;
547561
}
548562

549-
if (path_is_prefix_of_path("global", rel_path))
563+
if (in_tablespace)
564+
{
565+
char tmp_rel_path[MAXPGPATH];
566+
567+
sscanf_res = sscanf(rel_path, PG_TBLSPC_DIR "/%u/%[^/]/%u/",
568+
&(file->tblspcOid), tmp_rel_path,
569+
&(file->dbOid));
570+
571+
/*
572+
* We should skip other files and directories rather than
573+
* TABLESPACE_VERSION_DIRECTORY, if this is recursive tablespace.
574+
*/
575+
if (sscanf_res == 2 && strcmp(tmp_rel_path, TABLESPACE_VERSION_DIRECTORY) != 0)
576+
return CHECK_FALSE;
577+
578+
if (sscanf_res == 3 && S_ISDIR(file->mode) &&
579+
strcmp(tmp_rel_path, TABLESPACE_VERSION_DIRECTORY) == 0)
580+
file->is_database = true;
581+
}
582+
else if (path_is_prefix_of_path("global", rel_path))
550583
{
551584
file->tblspcOid = GLOBALTABLESPACE_OID;
552585

@@ -562,22 +595,10 @@ dir_check_file(const char *root, pgFile *file)
562595
if (S_ISDIR(file->mode) && strcmp(file->name, "base") != 0)
563596
file->is_database = true;
564597
}
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-
}
577598

578599
/* Do not backup ptrack_init files */
579600
if (S_ISREG(file->mode) && strcmp(file->name, "ptrack_init") == 0)
580-
return false;
601+
return CHECK_FALSE;
581602

582603
/*
583604
* Check files located inside database directories including directory
@@ -587,10 +608,10 @@ dir_check_file(const char *root, pgFile *file)
587608
file->name && file->name[0])
588609
{
589610
if (strcmp(file->name, "pg_internal.init") == 0)
590-
return false;
611+
return CHECK_FALSE;
591612
/* Do not backup temp files */
592613
else if (file->name[0] == 't' && isdigit(file->name[1]))
593-
return false;
614+
return CHECK_FALSE;
594615
else if (isdigit(file->name[0]))
595616
{
596617
char *fork_name;
@@ -605,14 +626,14 @@ dir_check_file(const char *root, pgFile *file)
605626

606627
/* Do not backup ptrack files */
607628
if (strcmp(file->forkName, "ptrack") == 0)
608-
return false;
629+
return CHECK_FALSE;
609630
}
610631
else
611632
{
612633
len = strlen(file->name);
613634
/* reloid.cfm */
614635
if (len > 3 && strcmp(file->name + len - 3, "cfm") == 0)
615-
return true;
636+
return CHECK_TRUE;
616637

617638
sscanf_res = sscanf(file->name, "%u.%d.%s", &(file->relOid),
618639
&(file->segno), suffix);
@@ -624,7 +645,7 @@ dir_check_file(const char *root, pgFile *file)
624645
}
625646
}
626647

627-
return true;
648+
return CHECK_TRUE;
628649
}
629650

630651
/*
@@ -659,6 +680,7 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
659680
{
660681
pgFile *file;
661682
char child[MAXPGPATH];
683+
char check_res;
662684

663685
join_path_components(child, parent->path, dent->d_name);
664686

@@ -694,21 +716,24 @@ dir_list_file_internal(parray *files, const char *root, pgFile *parent,
694716
continue;
695717
}
696718

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))
719+
if (exclude)
702720
{
703-
if (S_ISREG(file->mode))
721+
check_res = dir_check_file(root, file);
722+
if (check_res == CHECK_FALSE)
723+
{
724+
/* Skip */
704725
pgFileFree(file);
705-
/* Skip */
706-
continue;
726+
continue;
727+
}
728+
else if (check_res == CHECK_EXCLUDE_FALSE)
729+
{
730+
/* We add the directory itself which content was excluded */
731+
parray_append(files, file);
732+
continue;
733+
}
707734
}
708735

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

713738
/*
714739
* If the entry is a directory call dir_list_file_internal()
@@ -876,6 +901,7 @@ opt_tablespace_map(ConfigOption *opt, const char *arg)
876901
char *dst_ptr;
877902
const char *arg_ptr;
878903

904+
memset(cell, 0, sizeof(TablespaceListCell));
879905
dst_ptr = dst = cell->old_dir;
880906
for (arg_ptr = arg; *arg_ptr; arg_ptr++)
881907
{
@@ -1219,11 +1245,7 @@ print_file_list(FILE *out, const parray *files, const char *root)
12191245
if (file->is_datafile)
12201246
fprintf(out, ",\"segno\":\"%d\"", file->segno);
12211247

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

12291251
if (file->n_blocks != BLOCKNUM_INVALID)

0 commit comments

Comments
 (0)