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

Commit8c60e8f

Browse files
author
Vladimir Ershov
committed
Merge remote-tracking branch 'origin/PGPROEE9_6' into PGPROEE9_6_scheduler
2 parents9329731 +3cacdf4 commit8c60e8f

27 files changed

+2497
-452
lines changed

‎contrib/pg_probackup/backup.c

Lines changed: 70 additions & 116 deletions
Large diffs are not rendered by default.

‎contrib/pg_probackup/catalog.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,10 @@ pgBackupCreateDir(pgBackup *backup)
242242
char*subdirs[]= {DATABASE_DIR,NULL };
243243

244244
pgBackupGetPath(backup,path,lengthof(path),NULL);
245+
246+
if (!dir_is_empty(path))
247+
elog(ERROR,"backup destination is not empty \"%s\"",path);
248+
245249
dir_create_dir(path,DIR_PERMISSION);
246250

247251
/* create directories for actual backup files */
@@ -525,6 +529,8 @@ pgBackupGetPath(const pgBackup *backup, char *path, size_t len, const char *subd
525529
else
526530
snprintf(path,len,"%s/%s/%s",backup_path,BACKUPS_DIR,datetime);
527531
free(datetime);
532+
533+
make_native_path(path);
528534
}
529535

530536
void

‎contrib/pg_probackup/dir.c

Lines changed: 172 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ const char *pgdata_exclude_dir[] =
2525
"pg_xlog",
2626
"pg_stat_tmp",
2727
"pgsql_tmp",
28-
NULL,/* arclog_path will be set later */
2928
NULL,/* pg_log will be set later */
3029
NULL
3130
};
@@ -41,12 +40,18 @@ static char *pgdata_exclude_files[] =
4140
pgFile*pgFileNew(constchar*path,boolomit_symlink);
4241
staticintBlackListCompare(constvoid*str1,constvoid*str2);
4342

44-
/* create directory, also create parent directories if necessary */
43+
staticvoiddir_list_file_internal(parray*files,constchar*root,
44+
boolexclude,boolomit_symlink,
45+
booladd_root,parray*black_list);
46+
47+
/*
48+
* Create directory, also create parent directories if necessary.
49+
*/
4550
int
4651
dir_create_dir(constchar*dir,mode_tmode)
4752
{
48-
charcopy[MAXPGPATH];
49-
charparent[MAXPGPATH];
53+
charcopy[MAXPGPATH];
54+
charparent[MAXPGPATH];
5055

5156
strncpy(copy,dir,MAXPGPATH);
5257
strncpy(parent,dirname(copy),MAXPGPATH);
@@ -60,8 +65,7 @@ dir_create_dir(const char *dir, mode_t mode)
6065
{
6166
if (errno==EEXIST)/* already exist */
6267
return0;
63-
elog(ERROR,"cannot create directory \"%s\": %s",dir,
64-
strerror(errno));
68+
elog(ERROR,"cannot create directory \"%s\": %s",dir,strerror(errno));
6569
}
6670

6771
return0;
@@ -295,7 +299,7 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
295299
parray_qsort(files,pgFileComparePath);
296300
}
297301

298-
void
302+
staticvoid
299303
dir_list_file_internal(parray*files,constchar*root,boolexclude,
300304
boolomit_symlink,booladd_root,parray*black_list)
301305
{
@@ -327,11 +331,7 @@ dir_list_file_internal(parray *files, const char *root, bool exclude,
327331
else
328332
file_name++;
329333

330-
/*
331-
* If the item in the exclude list starts with '/', compare to the
332-
* absolute path of the directory. Otherwise compare to the directory
333-
* name portion.
334-
*/
334+
/* Check if we need to exclude file by name */
335335
for (i=0;pgdata_exclude_files[i];i++)
336336
if (strcmp(file_name,pgdata_exclude_files[i])==0)
337337
/* Skip */
@@ -416,13 +416,10 @@ dir_list_file_internal(parray *files, const char *root, bool exclude,
416416
break;
417417
}
418418
}
419-
else
419+
elseif (strcmp(dirname,pgdata_exclude_dir[i])==0)
420420
{
421-
if (strcmp(dirname,pgdata_exclude_dir[i])==0)
422-
{
423-
skip= true;
424-
break;
425-
}
421+
skip= true;
422+
break;
426423
}
427424
}
428425
if (skip)
@@ -468,74 +465,159 @@ dir_list_file_internal(parray *files, const char *root, bool exclude,
468465
}
469466
}
470467

471-
/* print mkdirs.sh */
468+
/*
469+
* List data directories excluding directories from
470+
* pgdata_exclude_dir array.
471+
*
472+
* **is_root** is a little bit hack. We exclude only first level of directories
473+
* and on the first level we check all files and directories.
474+
*/
472475
void
473-
dir_print_mkdirs_sh(FILE*out,constparray*files,constchar*root)
476+
list_data_directories(parray*files,constchar*path,boolis_root,
477+
boolexclude)
474478
{
475-
inti;
476-
477-
for (i=0;i<parray_num(files);i++)
479+
DIR*dir;
480+
structdirent*dent;
481+
intprev_errno;
482+
boolhas_child_dirs= false;
483+
484+
/* open directory and list contents */
485+
dir=opendir(path);
486+
if (dir==NULL)
487+
elog(ERROR,"cannot open directory \"%s\": %s",path,strerror(errno));
488+
489+
errno=0;
490+
while ((dent=readdir(dir)))
478491
{
479-
pgFile*file= (pgFile*)parray_get(files,i);
480-
if (S_ISDIR(file->mode))
492+
charchild[MAXPGPATH];
493+
boolskip= false;
494+
structstatst;
495+
496+
/* skip entries point current dir or parent dir */
497+
if (strcmp(dent->d_name,".")==0||
498+
strcmp(dent->d_name,"..")==0)
499+
continue;
500+
501+
join_path_components(child,path,dent->d_name);
502+
503+
if (lstat(child,&st)==-1)
504+
elog(ERROR,"cannot stat file \"%s\": %s",child,strerror(errno));
505+
506+
if (!S_ISDIR(st.st_mode))
481507
{
482-
if (strstr(file->path,root)==file->path&&
483-
*(file->path+strlen(root))=='/')
484-
{
485-
fprintf(out,"mkdir -m 700 -p %s\n",file->path+strlen(root)+1);
486-
}
508+
/* Stop reading the directory if we met file */
509+
if (!is_root)
510+
break;
487511
else
512+
continue;
513+
}
514+
515+
/* Check for exclude for the first level of listing */
516+
if (is_root&&exclude)
517+
{
518+
inti;
519+
520+
for (i=0;pgdata_exclude_dir[i];i++)
488521
{
489-
fprintf(out,"mkdir -m 700 -p %s\n",file->path);
522+
if (strcmp(dent->d_name,pgdata_exclude_dir[i])==0)
523+
{
524+
skip= true;
525+
break;
526+
}
490527
}
491528
}
492-
}
529+
if (skip)
530+
continue;
493531

494-
fprintf(out,"\n");
532+
has_child_dirs= true;
533+
list_data_directories(files,child, false,exclude);
534+
}
495535

496-
for (i=0;i<parray_num(files);i++)
536+
/* List only full and last directories */
537+
if (!is_root&& !has_child_dirs)
497538
{
498-
pgFile*file= (pgFile*)parray_get(files,i);
499-
if (S_ISLNK(file->mode))
500-
{
501-
fprintf(out,"rm -f %s\n",file->path+strlen(root)+1);
502-
fprintf(out,"ln -s %s %s\n",file->linked,file->path+strlen(root)+1);
503-
}
539+
pgFile*dir;
540+
541+
dir=pgFileNew(path, false);
542+
parray_append(files,dir);
504543
}
544+
545+
prev_errno=errno;
546+
closedir(dir);
547+
548+
if (prev_errno&&prev_errno!=ENOENT)
549+
elog(ERROR,"cannot read directory \"%s\": %s",
550+
path,strerror(prev_errno));
505551
}
506552

507-
/* print file list */
553+
/*
554+
* Read names of symbolik names of tablespaces with links to directories from
555+
* tablespace_map or tablespace_map.txt.
556+
*/
508557
void
509-
dir_print_file_list(FILE*out,constparray*files,constchar*root,constchar*prefix)
558+
read_tablespace_map(parray*files,constchar*backup_dir)
510559
{
511-
inti;
512-
introot_len=0;
560+
FILE*fp;
561+
chardb_path[MAXPGPATH],
562+
map_path[MAXPGPATH];
563+
charbuf[MAXPGPATH*2];
513564

514-
/* calculate length of root directory portion */
515-
if (root)
565+
join_path_components(db_path,backup_dir,DATABASE_DIR);
566+
join_path_components(map_path,db_path,"tablespace_map");
567+
568+
/* Exit if database/tablespace_map don't exists */
569+
if (!fileExists(map_path))
516570
{
517-
root_len=strlen(root);
518-
if (root[root_len-1]!='/')
519-
root_len++;
571+
elog(LOG,"there is no file tablespace_map");
572+
return;
520573
}
521574

575+
fp=fopen(map_path,"rt");
576+
if (fp==NULL)
577+
elog(ERROR,"cannot open \"%s\": %s",map_path,strerror(errno));
578+
579+
while (fgets(buf,lengthof(buf),fp))
580+
{
581+
charlink_name[MAXPGPATH],
582+
path[MAXPGPATH];
583+
pgFile*file;
584+
585+
if (sscanf(buf,"%s %s",link_name,path)!=2)
586+
elog(ERROR,"invalid format found in \"%s\"",map_path);
587+
588+
file=pgut_new(pgFile);
589+
memset(file,0,sizeof(pgFile));
590+
591+
file->path=pgut_malloc(strlen(link_name)+1);
592+
strcpy(file->path,link_name);
593+
594+
file->linked=pgut_malloc(strlen(path)+1);
595+
strcpy(file->linked,path);
596+
597+
parray_append(files,file);
598+
}
599+
600+
fclose(fp);
601+
}
602+
603+
/*
604+
* Print file list.
605+
*/
606+
void
607+
print_file_list(FILE*out,constparray*files,constchar*root)
608+
{
609+
size_ti;
610+
522611
/* print each file in the list */
523612
for (i=0;i<parray_num(files);i++)
524613
{
525-
pgFile*file= (pgFile*)parray_get(files,i);
526-
charpath[MAXPGPATH];
527-
char*ptr=file->path;
528-
chartype;
614+
pgFile*file= (pgFile*)parray_get(files,i);
615+
char*path=file->path;
616+
chartype;
529617

530618
/* omit root directory portion */
531-
if (root&&strstr(ptr,root)==ptr)
532-
ptr=JoinPathEnd(ptr,root);
533-
534-
/* append prefix if not NULL */
535-
if (prefix)
536-
join_path_components(path,prefix,ptr);
537-
else
538-
strcpy(path,ptr);
619+
if (root&&strstr(path,root)==path)
620+
path=JoinPathEnd(path,root);
539621

540622
if (S_ISREG(file->mode)&&file->is_datafile)
541623
type='F';
@@ -556,7 +638,8 @@ dir_print_file_list(FILE *out, const parray *files, const char *root, const char
556638
fprintf(out," %s",file->linked);
557639
else
558640
{
559-
chartimestamp[20];
641+
chartimestamp[20];
642+
560643
time2iso(timestamp,20,file->mtime);
561644
fprintf(out," %s",timestamp);
562645
}
@@ -683,45 +766,39 @@ dir_read_file_list(const char *root, const char *file_txt)
683766
}
684767

685768
/*
686-
*Copy contents ofdirectoryfrom_root into to_root.
769+
*Check ifdirectoryempty.
687770
*/
688-
void
689-
dir_copy_files(constchar*from_root,constchar*to_root)
771+
bool
772+
dir_is_empty(constchar*path)
690773
{
691-
size_ti;
692-
parray*files=parray_new();
774+
DIR*dir;
775+
structdirent*dir_ent;
693776

694-
/* don't copy root directory */
695-
dir_list_file(files,from_root, false, true, false);
696-
697-
for (i=0;i<parray_num(files);i++)
777+
dir=opendir(path);
778+
if (dir==NULL)
698779
{
699-
pgFile*file= (pgFile*)parray_get(files,i);
700-
701-
if (S_ISDIR(file->mode))
702-
{
703-
charto_path[MAXPGPATH];
780+
/* Directory in path doesn't exist */
781+
if (errno==ENOENT)
782+
return true;
783+
elog(ERROR,"cannot open directory \"%s\": %s",path,strerror(errno));
784+
}
704785

705-
join_path_components(to_path,to_root,
706-
file->path+strlen(from_root)+1);
786+
errno=0;
787+
while ((dir_ent=readdir(dir)))
788+
{
789+
/* Skip entries point current dir or parent dir */
790+
if (strcmp(dir_ent->d_name,".")==0||
791+
strcmp(dir_ent->d_name,"..")==0)
792+
continue;
707793

708-
if (verbose&& !check)
709-
elog(LOG,"creating directory \"%s\"",
710-
file->path+strlen(from_root)+1);
711-
if (!check)
712-
dir_create_dir(to_path,DIR_PERMISSION);
713-
}
714-
elseif (S_ISREG(file->mode))
715-
{
716-
if (verbose&& !check)
717-
elog(LOG,"copying \"%s\"",
718-
file->path+strlen(from_root)+1);
719-
if (!check)
720-
copy_file(from_root,to_root,file);
721-
}
794+
/* Directory is not empty */
795+
closedir(dir);
796+
return false;
722797
}
798+
if (errno)
799+
elog(ERROR,"cannot read directory \"%s\": %s",path,strerror(errno));
800+
801+
closedir(dir);
723802

724-
/* cleanup */
725-
parray_walk(files,pgFileFree);
726-
parray_free(files);
803+
return true;
727804
}

‎contrib/pg_probackup/doc/pg_probackup.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,12 @@ Specifies whether to stop just after the specified recovery target (true), or ju
477477

478478
Specifies recovering into a particular timeline.
479479

480+
-T
481+
--tablespace-mapping=OLDDIR=NEWDIR
482+
483+
Relocate the tablespace in directory`OLDDIR` to`NEWDIR` during restore. Both
484+
`OLDDIR` and`NEWDIR` must be absolute paths.
485+
480486
###Delete options:
481487

482488
--wal

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp