Skip to content

Commit 2e3adf1

Browse files
committed
check emptyness of dest_pgdata
1 parent b294557 commit 2e3adf1

File tree

1 file changed

+47
-22
lines changed

1 file changed

+47
-22
lines changed

src/catchup.c

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@
2828
*/
2929
static PGconn *catchup_collect_info(PGNodeInfo *source_node_info, const char *source_pgdata, const char *dest_pgdata);
3030
static void catchup_preflight_checks(PGNodeInfo *source_node_info, PGconn *source_conn, const char *source_pgdata,
31-
const char *dest_pgdata, bool dest_pgdata_is_empty);
31+
const char *dest_pgdata);
3232
static void do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *source_conn,
33-
PGNodeInfo *nodeInfo, bool no_sync, bool backup_logs,
34-
bool dest_pgdata_is_empty);
33+
PGNodeInfo *nodeInfo, bool no_sync, bool backup_logs);
3534
static void *catchup_thread_runner(void *arg);
3635

3736
/*
@@ -44,13 +43,12 @@ do_catchup(const char *source_pgdata, const char *dest_pgdata, int num_threads)
4443
PGNodeInfo source_node_info;
4544
bool no_sync = false;
4645
bool backup_logs = false;
47-
bool dest_pgdata_is_empty = dir_is_empty(dest_pgdata, FIO_LOCAL_HOST);
4846

4947
source_conn = catchup_collect_info(&source_node_info, source_pgdata, dest_pgdata);
50-
catchup_preflight_checks(&source_node_info, source_conn, source_pgdata, dest_pgdata, dest_pgdata_is_empty);
48+
catchup_preflight_checks(&source_node_info, source_conn, source_pgdata, dest_pgdata);
5149

5250
do_catchup_instance(source_pgdata, dest_pgdata, source_conn, &source_node_info,
53-
no_sync, backup_logs, dest_pgdata_is_empty);
51+
no_sync, backup_logs);
5452

5553
//REVIEW: Are we going to do that before release?
5654
/* TODO: show the amount of transfered data in bytes and calculate incremental ratio */
@@ -66,6 +64,7 @@ static PGconn *
6664
catchup_collect_info(PGNodeInfo *source_node_info, const char *source_pgdata, const char *dest_pgdata)
6765
{
6866
PGconn *source_conn;
67+
6968
/* Initialize PGInfonode */
7069
pgNodeInit(source_node_info);
7170

@@ -85,8 +84,6 @@ catchup_collect_info(PGNodeInfo *source_node_info, const char *source_pgdata, co
8584
/* Do some compatibility checks and fill basic info about PG instance */
8685
source_conn = pgdata_basic_setup(instance_config.conn_opt, source_node_info);
8786

88-
//REVIEW Please adjust the comment. Do we need this code for catchup at all?
89-
/* below perform checks specific for backup command */
9087
#if PG_VERSION_NUM >= 110000
9188
if (!RetrieveWalSegSize(source_conn))
9289
elog(ERROR, "Failed to retrieve wal_segment_size");
@@ -122,10 +119,42 @@ catchup_collect_info(PGNodeInfo *source_node_info, const char *source_pgdata, co
122119
*/
123120
static void
124121
catchup_preflight_checks(PGNodeInfo *source_node_info, PGconn *source_conn,
125-
const char *source_pgdata, const char *dest_pgdata, bool dest_pgdata_is_empty)
122+
const char *source_pgdata, const char *dest_pgdata)
126123
{
127-
//REVIEW Let's fix it before release.
128-
// TODO: add sanity check that source PGDATA is not empty
124+
/* TODO
125+
* gsmol - fallback to FULL mode if dest PGDATA is empty
126+
* kulaginm -- I think this is a harmful feature. If user requested an incremental catchup, then
127+
* he expects that this will be done quickly and efficiently. If, for example, he made a mistake
128+
* with dest_dir, then he will receive a second full copy instead of an error message, and I think
129+
* that in some cases he would prefer the error.
130+
* I propose in future versions to offer a backup_mode auto, in which we will look to the dest_dir
131+
* and decide which of the modes will be the most effective.
132+
* I.e.:
133+
* if(requested_backup_mode == BACKUP_MODE_DIFF_AUTO)
134+
* {
135+
* if(dest_pgdata_is_empty)
136+
* backup_mode = BACKUP_MODE_FULL;
137+
* else
138+
* if(ptrack supported and applicable)
139+
* backup_mode = BACKUP_MODE_DIFF_PTRACK;
140+
* else
141+
* backup_mode = BACKUP_MODE_DIFF_DELTA;
142+
* }
143+
*/
144+
145+
if (dir_is_empty(dest_pgdata, FIO_LOCAL_HOST))
146+
{
147+
if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK ||
148+
current.backup_mode == BACKUP_MODE_DIFF_DELTA)
149+
elog(ERROR, "\"%s\" is empty but incremental catchup mode requested.",
150+
dest_pgdata);
151+
}
152+
else /* dest dir not empty */
153+
{
154+
if (current.backup_mode == BACKUP_MODE_FULL)
155+
elog(ERROR, "Can't perform full catchup into not empty directory \"%s\".",
156+
dest_pgdata);
157+
}
129158

130159
/* Check that connected PG instance and source PGDATA are the same */
131160
check_system_identifiers(source_conn, source_pgdata);
@@ -141,7 +170,7 @@ catchup_preflight_checks(PGNodeInfo *source_node_info, PGconn *source_conn,
141170
elog(ERROR, "Ptrack is disabled");
142171
}
143172

144-
if (!dest_pgdata_is_empty &&
173+
if (current.backup_mode != BACKUP_MODE_FULL &&
145174
check_incremental_compatibility(dest_pgdata,
146175
instance_config.system_identifier,
147176
INCR_CHECKSUM) != DEST_OK)
@@ -157,12 +186,10 @@ catchup_preflight_checks(PGNodeInfo *source_node_info, PGconn *source_conn,
157186
/*
158187
* TODO:
159188
* - add description
160-
* - fallback to FULL mode if dest PGDATA is empty
161189
*/
162190
static void
163191
do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *source_conn,
164-
PGNodeInfo *source_node_info, bool no_sync, bool backup_logs,
165-
bool dest_pgdata_is_empty)
192+
PGNodeInfo *source_node_info, bool no_sync, bool backup_logs)
166193
{
167194
int i;
168195
char dest_xlog_path[MAXPGPATH];
@@ -208,9 +235,8 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
208235

209236
//REVIEW I wonder, if we can move this piece above and call before pg_start backup()?
210237
//It seems to be a part of setup phase.
211-
if (!dest_pgdata_is_empty &&
212-
(current.backup_mode == BACKUP_MODE_DIFF_PTRACK ||
213-
current.backup_mode == BACKUP_MODE_DIFF_DELTA))
238+
if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK ||
239+
current.backup_mode == BACKUP_MODE_DIFF_DELTA)
214240
{
215241
dest_filelist = parray_new();
216242
dir_list_file(dest_filelist, dest_pgdata,
@@ -423,9 +449,8 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
423449
* remove absent source files in dest (dropped tables, etc...)
424450
* note: global/pg_control will also be deleted here
425451
*/
426-
if (!dest_pgdata_is_empty &&
427-
(current.backup_mode == BACKUP_MODE_DIFF_PTRACK ||
428-
current.backup_mode == BACKUP_MODE_DIFF_DELTA))
452+
if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK ||
453+
current.backup_mode == BACKUP_MODE_DIFF_DELTA)
429454
{
430455
elog(INFO, "Removing redundant files in destination directory");
431456
parray_qsort(dest_filelist, pgFileCompareRelPathWithExternalDesc);
@@ -676,7 +701,7 @@ do_catchup_instance(const char *source_pgdata, const char *dest_pgdata, PGconn *
676701
}
677702

678703
/* Cleanup */
679-
if (!dest_pgdata_is_empty && dest_filelist)
704+
if (dest_filelist)
680705
{
681706
parray_walk(dest_filelist, pgFileFree);
682707
parray_free(dest_filelist);

0 commit comments

Comments
 (0)