Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd26a68f

Browse files
kulaginmdlepikhova
authored andcommitted
[PBCKP-259] fix for 'ERROR: Cannot create directory for older backup'… (#526)
* [PBCKP-259] fix for 'ERROR: Cannot create directory for older backup', rewrite --start_time implementation* rewritten5f2283c* fixes for several tests* disabled tests.merge.MergeTest.test_merge_backup_from_future and tests.restore.RestoreTest.test_restore_backup_from_future as incorrect for nowCo-authored-by: d.lepikhova <d.lepikhova@postgrespro.ru>
1 parentd749372 commitd26a68f

File tree

8 files changed

+217
-356
lines changed

8 files changed

+217
-356
lines changed

‎src/backup.c

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -685,15 +685,22 @@ pgdata_basic_setup(ConnectionOptions conn_opt, PGNodeInfo *nodeInfo)
685685

686686
/*
687687
* Entry point of pg_probackup BACKUP subcommand.
688+
*
689+
* if start_time == INVALID_BACKUP_ID then we can generate backup_id
688690
*/
689691
int
690692
do_backup(InstanceState*instanceState,pgSetBackupParams*set_backup_params,
691693
boolno_validate,boolno_sync,boolbackup_logs,time_tstart_time)
692694
{
693695
PGconn*backup_conn=NULL;
694696
PGNodeInfonodeInfo;
697+
time_tlatest_backup_id=INVALID_BACKUP_ID;
695698
charpretty_bytes[20];
696699

700+
if (!instance_config.pgdata)
701+
elog(ERROR,"required parameter not specified: PGDATA "
702+
"(-D, --pgdata)");
703+
697704
/* Initialize PGInfonode */
698705
pgNodeInit(&nodeInfo);
699706

@@ -702,12 +709,55 @@ do_backup(InstanceState *instanceState, pgSetBackupParams *set_backup_params,
702709
(pg_strcasecmp(instance_config.external_dir_str,"none")!=0))
703710
current.external_dir_str=instance_config.external_dir_str;
704711

705-
/* Create backup directory and BACKUP_CONTROL_FILE */
706-
pgBackupCreateDir(&current,instanceState,start_time);
712+
/* Find latest backup_id */
713+
{
714+
parray*backup_list=catalog_get_backup_list(instanceState,INVALID_BACKUP_ID);
707715

708-
if (!instance_config.pgdata)
709-
elog(ERROR,"required parameter not specified: PGDATA "
710-
"(-D, --pgdata)");
716+
if (parray_num(backup_list)>0)
717+
latest_backup_id= ((pgBackup*)parray_get(backup_list,0))->backup_id;
718+
719+
parray_walk(backup_list,pgBackupFree);
720+
parray_free(backup_list);
721+
}
722+
723+
/* Try to pick backup_id and create backup directory with BACKUP_CONTROL_FILE */
724+
if (start_time!=INVALID_BACKUP_ID)
725+
{
726+
/* If user already choosed backup_id for us, then try to use it. */
727+
if (start_time <=latest_backup_id)
728+
/* don't care about freeing base36enc_dup memory, we exit anyway */
729+
elog(ERROR,"Can't assign backup_id from requested start_time (%s), "
730+
"this time must be later that backup %s",
731+
base36enc_dup(start_time),base36enc_dup(latest_backup_id));
732+
733+
current.backup_id=start_time;
734+
pgBackupInitDir(&current,instanceState->instance_backup_subdir_path);
735+
}
736+
else
737+
{
738+
/* We can generate our own unique backup_id
739+
* Sometimes (when we try to backup twice in one second)
740+
* backup_id will be duplicated -> try more times.
741+
*/
742+
intattempts=10;
743+
744+
if (time(NULL)<latest_backup_id)
745+
elog(ERROR,"Can't assign backup_id, there is already a backup in future (%s)",
746+
base36enc(latest_backup_id));
747+
748+
do
749+
{
750+
current.backup_id=time(NULL);
751+
pgBackupInitDir(&current,instanceState->instance_backup_subdir_path);
752+
if (current.backup_id==INVALID_BACKUP_ID)
753+
sleep(1);
754+
}
755+
while (current.backup_id==INVALID_BACKUP_ID&&attempts-->0);
756+
}
757+
758+
/* If creation of backup dir was unsuccessful, there will be WARNINGS in logs already */
759+
if (current.backup_id==INVALID_BACKUP_ID)
760+
elog(ERROR,"Can't create backup directory");
711761

712762
/* Update backup status and other metainfo. */
713763
current.status=BACKUP_STATUS_RUNNING;

‎src/catalog.c

Lines changed: 38 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ static pgBackup* get_closest_backup(timelineInfo *tlinfo);
2323
staticpgBackup*get_oldest_backup(timelineInfo*tlinfo);
2424
staticconstchar*backupModes[]= {"","PAGE","PTRACK","DELTA","FULL"};
2525
staticpgBackup*readBackupControlFile(constchar*path);
26-
staticvoidcreate_backup_dir(pgBackup*backup,constchar*backup_instance_path);
26+
staticintcreate_backup_dir(pgBackup*backup,constchar*backup_instance_path);
2727

2828
staticboolbackup_lock_exit_hook_registered= false;
2929
staticparray*locks=NULL;
@@ -976,6 +976,7 @@ catalog_get_backup_list(InstanceState *instanceState, time_t requested_backup_id
976976
}
977977
elseif (strcmp(base36enc(backup->start_time),data_ent->d_name)!=0)
978978
{
979+
/* TODO there is no such guarantees */
979980
elog(WARNING,"backup ID in control file \"%s\" doesn't match name of the backup folder \"%s\"",
980981
base36enc(backup->start_time),backup_conf_path);
981982
}
@@ -1421,21 +1422,33 @@ get_multi_timeline_parent(parray *backup_list, parray *tli_list,
14211422
returnNULL;
14221423
}
14231424

1424-
/* Create backup directory in $BACKUP_PATH
1425-
* Note, that backup_id attribute is updated,
1426-
* so it is possible to get diffrent values in
1425+
/*
1426+
* Create backup directory in $BACKUP_PATH
1427+
* (with proposed backup->backup_id)
1428+
* and initialize this directory.
1429+
* If creation of directory fails, then
1430+
* backup_id will be cleared (set to INVALID_BACKUP_ID).
1431+
* It is possible to get diffrent values in
14271432
* pgBackup.start_time and pgBackup.backup_id.
14281433
* It may be ok or maybe not, so it's up to the caller
14291434
* to fix it or let it be.
14301435
*/
14311436
void
1432-
pgBackupCreateDir(pgBackup*backup,InstanceState*instanceState,time_tstart_time)
1437+
pgBackupInitDir(pgBackup*backup,constchar*backup_instance_path)
14331438
{
1434-
inti;
1435-
parray*subdirs=parray_new();
1436-
parray*backups;
1437-
pgBackup*target_backup;
1439+
inti;
1440+
chartemp[MAXPGPATH];
1441+
parray*subdirs;
14381442

1443+
/* Try to create backup directory at first */
1444+
if (create_backup_dir(backup,backup_instance_path)!=0)
1445+
{
1446+
/* Clear backup_id as indication of error */
1447+
backup->backup_id=INVALID_BACKUP_ID;
1448+
return;
1449+
}
1450+
1451+
subdirs=parray_new();
14391452
parray_append(subdirs,pg_strdup(DATABASE_DIR));
14401453

14411454
/* Add external dirs containers */
@@ -1447,38 +1460,13 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14471460
false);
14481461
for (i=0;i<parray_num(external_list);i++)
14491462
{
1450-
chartemp[MAXPGPATH];
14511463
/* Numeration of externaldirs starts with 1 */
14521464
makeExternalDirPathByNum(temp,EXTERNAL_DIR,i+1);
14531465
parray_append(subdirs,pg_strdup(temp));
14541466
}
14551467
free_dir_list(external_list);
14561468
}
14571469

1458-
/* Get list of all backups*/
1459-
backups=catalog_get_backup_list(instanceState,INVALID_BACKUP_ID);
1460-
if (parray_num(backups)>0)
1461-
{
1462-
target_backup= (pgBackup*)parray_get(backups,0);
1463-
if (start_time>target_backup->backup_id)
1464-
{
1465-
backup->backup_id=start_time;
1466-
create_backup_dir(backup,instanceState->instance_backup_subdir_path);
1467-
}
1468-
else
1469-
{
1470-
elog(ERROR,"Cannot create directory for older backup");
1471-
}
1472-
}
1473-
else
1474-
{
1475-
backup->backup_id=start_time;
1476-
create_backup_dir(backup,instanceState->instance_backup_subdir_path);
1477-
}
1478-
1479-
if (backup->backup_id==0)
1480-
elog(ERROR,"Cannot create backup directory: %s",strerror(errno));
1481-
14821470
backup->database_dir=pgut_malloc(MAXPGPATH);
14831471
join_path_components(backup->database_dir,backup->root_dir,DATABASE_DIR);
14841472

@@ -1488,10 +1476,8 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14881476
/* create directories for actual backup files */
14891477
for (i=0;i<parray_num(subdirs);i++)
14901478
{
1491-
charpath[MAXPGPATH];
1492-
1493-
join_path_components(path,backup->root_dir,parray_get(subdirs,i));
1494-
fio_mkdir(FIO_BACKUP_HOST,path,DIR_PERMISSION, false);
1479+
join_path_components(temp,backup->root_dir,parray_get(subdirs,i));
1480+
fio_mkdir(FIO_BACKUP_HOST,temp,DIR_PERMISSION, false);
14951481
}
14961482

14971483
free_dir_list(subdirs);
@@ -1500,33 +1486,26 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
15001486
/*
15011487
* Create root directory for backup,
15021488
* update pgBackup.root_dir if directory creation was a success
1489+
* Return values (same as dir_create_dir()):
1490+
* 0 - ok
1491+
* -1 - error (warning message already emitted)
15031492
*/
1504-
void
1493+
int
15051494
create_backup_dir(pgBackup*backup,constchar*backup_instance_path)
15061495
{
1507-
intattempts=10;
1496+
intrc;
1497+
charpath[MAXPGPATH];
15081498

1509-
while (attempts--)
1510-
{
1511-
intrc;
1512-
charpath[MAXPGPATH];
1513-
1514-
join_path_components(path,backup_instance_path,base36enc(backup->backup_id));
1499+
join_path_components(path,backup_instance_path,base36enc(backup->backup_id));
15151500

1516-
rc=fio_mkdir(FIO_BACKUP_HOST,path,DIR_PERMISSION, true);
1517-
1518-
if (rc==0)
1519-
{
1520-
backup->root_dir=pgut_strdup(path);
1521-
return;
1522-
}
1523-
else
1524-
{
1525-
elog(WARNING,"Cannot create directory \"%s\": %s",path,strerror(errno));
1526-
sleep(1);
1527-
}
1528-
}
1501+
/* TODO: add wrapper for remote mode */
1502+
rc=fio_mkdir(FIO_BACKUP_HOST,path,DIR_PERMISSION, true);
15291503

1504+
if (rc==0)
1505+
backup->root_dir=pgut_strdup(path);
1506+
else
1507+
elog(WARNING,"Cannot create directory \"%s\": %s",path,strerror(errno));
1508+
returnrc;
15301509
}
15311510

15321511
/*

‎src/pg_probackup.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pid_t my_pid = 0;
7878
__threadintmy_thread_num=1;
7979
boolprogress= false;
8080
boolno_sync= false;
81-
time_tstart_time=0;
81+
time_tstart_time=INVALID_BACKUP_ID;
8282
char*replication_slot=NULL;
8383
booltemp_slot= false;
8484
boolperm_slot= false;
@@ -200,7 +200,6 @@ static ConfigOption cmd_options[] =
200200
{'s','i',"backup-id",&backup_id_string,SOURCE_CMD_STRICT },
201201
{'b',133,"no-sync",&no_sync,SOURCE_CMD_STRICT },
202202
{'b',134,"no-color",&no_color,SOURCE_CMD_STRICT },
203-
{'U',241,"start-time",&start_time,SOURCE_CMD_STRICT },
204203
/* backup options */
205204
{'b',180,"backup-pg-log",&backup_logs,SOURCE_CMD_STRICT },
206205
{'f','b',"backup-mode",opt_backup_mode,SOURCE_CMD_STRICT },
@@ -213,6 +212,7 @@ static ConfigOption cmd_options[] =
213212
{'b',184,"merge-expired",&merge_expired,SOURCE_CMD_STRICT },
214213
{'b',185,"dry-run",&dry_run,SOURCE_CMD_STRICT },
215214
{'s',238,"note",&backup_note,SOURCE_CMD_STRICT },
215+
{'U',241,"start-time",&start_time,SOURCE_CMD_STRICT },
216216
/* catchup options */
217217
{'s',239,"source-pgdata",&catchup_source_pgdata,SOURCE_CMD_STRICT },
218218
{'s',240,"destination-pgdata",&catchup_destination_pgdata,SOURCE_CMD_STRICT },
@@ -975,9 +975,7 @@ main(int argc, char *argv[])
975975
caseBACKUP_CMD:
976976
{
977977
current.stream=stream_wal;
978-
if (start_time==0)
979-
start_time=current_time;
980-
else
978+
if (start_time!=INVALID_BACKUP_ID)
981979
elog(WARNING,"Please do not use the --start-time option to start backup. "
982980
"This is a service option required to work with other extensions. "
983981
"We do not guarantee future support for this flag.");

‎src/pg_probackup.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,10 @@ struct pgBackup
439439
{
440440
BackupModebackup_mode;/* Mode - one of BACKUP_MODE_xxx above*/
441441
time_tbackup_id;/* Identifier of the backup.
442-
* Currently it's the same as start_time */
442+
* By default it's the same as start_time
443+
* but can be increased if same backup_id
444+
* already exists. It can be also set by
445+
* start_time parameter */
443446
BackupStatusstatus;/* Status - one of BACKUP_STATUS_xxx above*/
444447
TimeLineIDtli;/* timeline of start and stop backup lsns */
445448
XLogRecPtrstart_lsn;/* backup's starting transaction log location */
@@ -969,7 +972,7 @@ extern void write_backup_filelist(pgBackup *backup, parray *files,
969972
constchar*root,parray*external_list,boolsync);
970973

971974

972-
externvoidpgBackupCreateDir(pgBackup*backup,InstanceState*instanceState,time_tstart_time);
975+
externvoidpgBackupInitDir(pgBackup*backup,constchar*backup_instance_path);
973976
externvoidpgNodeInit(PGNodeInfo*node);
974977
externvoidpgBackupInit(pgBackup*backup);
975978
externvoidpgBackupFree(void*backup);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp