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

Commit1bb0762

Browse files
[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 parent95471ac commit1bb0762

File tree

8 files changed

+217
-357
lines changed

8 files changed

+217
-357
lines changed

‎src/backup.c

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

693693
/*
694694
* Entry point of pg_probackup BACKUP subcommand.
695+
*
696+
* if start_time == INVALID_BACKUP_ID then we can generate backup_id
695697
*/
696698
int
697699
do_backup(InstanceState*instanceState,pgSetBackupParams*set_backup_params,
698700
boolno_validate,boolno_sync,boolbackup_logs,time_tstart_time)
699701
{
700702
PGconn*backup_conn=NULL;
701703
PGNodeInfonodeInfo;
704+
time_tlatest_backup_id=INVALID_BACKUP_ID;
702705
charpretty_bytes[20];
703706

707+
if (!instance_config.pgdata)
708+
elog(ERROR,"required parameter not specified: PGDATA "
709+
"(-D, --pgdata)");
710+
704711
/* Initialize PGInfonode */
705712
pgNodeInit(&nodeInfo);
706713

@@ -709,12 +716,55 @@ do_backup(InstanceState *instanceState, pgSetBackupParams *set_backup_params,
709716
(pg_strcasecmp(instance_config.external_dir_str,"none")!=0))
710717
current.external_dir_str=instance_config.external_dir_str;
711718

712-
/* Create backup directory and BACKUP_CONTROL_FILE */
713-
pgBackupCreateDir(&current,instanceState,start_time);
719+
/* Find latest backup_id */
720+
{
721+
parray*backup_list=catalog_get_backup_list(instanceState,INVALID_BACKUP_ID);
714722

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

719769
/* Update backup status and other metainfo. */
720770
current.status=BACKUP_STATUS_RUNNING;

‎src/catalog.c

Lines changed: 38 additions & 60 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;
@@ -969,6 +969,7 @@ catalog_get_backup_list(InstanceState *instanceState, time_t requested_backup_id
969969
}
970970
elseif (strcmp(base36enc(backup->start_time),data_ent->d_name)!=0)
971971
{
972+
/* TODO there is no such guarantees */
972973
elog(WARNING,"backup ID in control file \"%s\" doesn't match name of the backup folder \"%s\"",
973974
base36enc(backup->start_time),backup_conf_path);
974975
}
@@ -1411,22 +1412,34 @@ get_multi_timeline_parent(parray *backup_list, parray *tli_list,
14111412
returnNULL;
14121413
}
14131414

1414-
/* Create backup directory in $BACKUP_PATH
1415-
* Note, that backup_id attribute is updated,
1416-
* so it is possible to get diffrent values in
1415+
/*
1416+
* Create backup directory in $BACKUP_PATH
1417+
* (with proposed backup->backup_id)
1418+
* and initialize this directory.
1419+
* If creation of directory fails, then
1420+
* backup_id will be cleared (set to INVALID_BACKUP_ID).
1421+
* It is possible to get diffrent values in
14171422
* pgBackup.start_time and pgBackup.backup_id.
14181423
* It may be ok or maybe not, so it's up to the caller
14191424
* to fix it or let it be.
14201425
*/
14211426

14221427
void
1423-
pgBackupCreateDir(pgBackup*backup,InstanceState*instanceState,time_tstart_time)
1428+
pgBackupInitDir(pgBackup*backup,constchar*backup_instance_path)
14241429
{
1425-
inti;
1426-
parray*subdirs=parray_new();
1427-
parray*backups;
1428-
pgBackup*target_backup;
1430+
inti;
1431+
chartemp[MAXPGPATH];
1432+
parray*subdirs;
14291433

1434+
/* Try to create backup directory at first */
1435+
if (create_backup_dir(backup,backup_instance_path)!=0)
1436+
{
1437+
/* Clear backup_id as indication of error */
1438+
backup->backup_id=INVALID_BACKUP_ID;
1439+
return;
1440+
}
1441+
1442+
subdirs=parray_new();
14301443
parray_append(subdirs,pg_strdup(DATABASE_DIR));
14311444

14321445
/* Add external dirs containers */
@@ -1438,38 +1451,13 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14381451
false);
14391452
for (i=0;i<parray_num(external_list);i++)
14401453
{
1441-
chartemp[MAXPGPATH];
14421454
/* Numeration of externaldirs starts with 1 */
14431455
makeExternalDirPathByNum(temp,EXTERNAL_DIR,i+1);
14441456
parray_append(subdirs,pg_strdup(temp));
14451457
}
14461458
free_dir_list(external_list);
14471459
}
14481460

1449-
/* Get list of all backups*/
1450-
backups=catalog_get_backup_list(instanceState,INVALID_BACKUP_ID);
1451-
if (parray_num(backups)>0)
1452-
{
1453-
target_backup= (pgBackup*)parray_get(backups,0);
1454-
if (start_time>target_backup->backup_id)
1455-
{
1456-
backup->backup_id=start_time;
1457-
create_backup_dir(backup,instanceState->instance_backup_subdir_path);
1458-
}
1459-
else
1460-
{
1461-
elog(ERROR,"Cannot create directory for older backup");
1462-
}
1463-
}
1464-
else
1465-
{
1466-
backup->backup_id=start_time;
1467-
create_backup_dir(backup,instanceState->instance_backup_subdir_path);
1468-
}
1469-
1470-
if (backup->backup_id==0)
1471-
elog(ERROR,"Cannot create backup directory: %s",strerror(errno));
1472-
14731461
backup->database_dir=pgut_malloc(MAXPGPATH);
14741462
join_path_components(backup->database_dir,backup->root_dir,DATABASE_DIR);
14751463

@@ -1479,10 +1467,8 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14791467
/* create directories for actual backup files */
14801468
for (i=0;i<parray_num(subdirs);i++)
14811469
{
1482-
charpath[MAXPGPATH];
1483-
1484-
join_path_components(path,backup->root_dir,parray_get(subdirs,i));
1485-
fio_mkdir(path,DIR_PERMISSION,FIO_BACKUP_HOST);
1470+
join_path_components(temp,backup->root_dir,parray_get(subdirs,i));
1471+
fio_mkdir(temp,DIR_PERMISSION,FIO_BACKUP_HOST);
14861472
}
14871473

14881474
free_dir_list(subdirs);
@@ -1491,34 +1477,26 @@ pgBackupCreateDir(pgBackup *backup, InstanceState *instanceState, time_t start_t
14911477
/*
14921478
* Create root directory for backup,
14931479
* update pgBackup.root_dir if directory creation was a success
1480+
* Return values (same as dir_create_dir()):
1481+
* 0 - ok
1482+
* -1 - error (warning message already emitted)
14941483
*/
1495-
void
1484+
int
14961485
create_backup_dir(pgBackup*backup,constchar*backup_instance_path)
14971486
{
1498-
intattempts=10;
1487+
intrc;
1488+
charpath[MAXPGPATH];
14991489

1500-
while (attempts--)
1501-
{
1502-
intrc;
1503-
charpath[MAXPGPATH];
1504-
1505-
join_path_components(path,backup_instance_path,base36enc(backup->backup_id));
1490+
join_path_components(path,backup_instance_path,base36enc(backup->backup_id));
15061491

1507-
/* TODO: add wrapper for remote mode */
1508-
rc=dir_create_dir(path,DIR_PERMISSION, true);
1509-
1510-
if (rc==0)
1511-
{
1512-
backup->root_dir=pgut_strdup(path);
1513-
return;
1514-
}
1515-
else
1516-
{
1517-
elog(WARNING,"Cannot create directory \"%s\": %s",path,strerror(errno));
1518-
sleep(1);
1519-
}
1520-
}
1492+
/* TODO: add wrapper for remote mode */
1493+
rc=dir_create_dir(path,DIR_PERMISSION, true);
15211494

1495+
if (rc==0)
1496+
backup->root_dir=pgut_strdup(path);
1497+
else
1498+
elog(WARNING,"Cannot create directory \"%s\": %s",path,strerror(errno));
1499+
returnrc;
15221500
}
15231501

15241502
/*

‎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
#ifPG_VERSION_NUM >=100000
8383
char*replication_slot=NULL;
8484
booltemp_slot= false;
@@ -202,7 +202,6 @@ static ConfigOption cmd_options[] =
202202
{'s','i',"backup-id",&backup_id_string,SOURCE_CMD_STRICT },
203203
{'b',133,"no-sync",&no_sync,SOURCE_CMD_STRICT },
204204
{'b',134,"no-color",&no_color,SOURCE_CMD_STRICT },
205-
{'U',241,"start-time",&start_time,SOURCE_CMD_STRICT },
206205
/* backup options */
207206
{'b',180,"backup-pg-log",&backup_logs,SOURCE_CMD_STRICT },
208207
{'f','b',"backup-mode",opt_backup_mode,SOURCE_CMD_STRICT },
@@ -217,6 +216,7 @@ static ConfigOption cmd_options[] =
217216
{'b',184,"merge-expired",&merge_expired,SOURCE_CMD_STRICT },
218217
{'b',185,"dry-run",&dry_run,SOURCE_CMD_STRICT },
219218
{'s',238,"note",&backup_note,SOURCE_CMD_STRICT },
219+
{'U',241,"start-time",&start_time,SOURCE_CMD_STRICT },
220220
/* catchup options */
221221
{'s',239,"source-pgdata",&catchup_source_pgdata,SOURCE_CMD_STRICT },
222222
{'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
@@ -450,7 +450,10 @@ struct pgBackup
450450
{
451451
BackupModebackup_mode;/* Mode - one of BACKUP_MODE_xxx above*/
452452
time_tbackup_id;/* Identifier of the backup.
453-
* Currently it's the same as start_time */
453+
* By default it's the same as start_time
454+
* but can be increased if same backup_id
455+
* already exists. It can be also set by
456+
* start_time parameter */
454457
BackupStatusstatus;/* Status - one of BACKUP_STATUS_xxx above*/
455458
TimeLineIDtli;/* timeline of start and stop backup lsns */
456459
XLogRecPtrstart_lsn;/* backup's starting transaction log location */
@@ -985,7 +988,7 @@ extern void write_backup_filelist(pgBackup *backup, parray *files,
985988
constchar*root,parray*external_list,boolsync);
986989

987990

988-
externvoidpgBackupCreateDir(pgBackup*backup,InstanceState*instanceState,time_tstart_time);
991+
externvoidpgBackupInitDir(pgBackup*backup,constchar*backup_instance_path);
989992
externvoidpgNodeInit(PGNodeInfo*node);
990993
externvoidpgBackupInit(pgBackup*backup);
991994
externvoidpgBackupFree(void*backup);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp