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

Commit773e4d5

Browse files
committed
Avoid including tablespaces inside PGDATA twice in base backups
If a tablespace was crated inside PGDATA it was backed up both as partof the PGDATA backup and as the backup of the tablespace. Avoid thisby skipping any directory inside PGDATA that contains one of the activetablespaces.Dimitri Fontaine and Magnus Hagander
1 parent9484982 commit773e4d5

File tree

1 file changed

+53
-7
lines changed

1 file changed

+53
-7
lines changed

‎src/backend/replication/basebackup.c

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include"lib/stringinfo.h"
2424
#include"libpq/libpq.h"
2525
#include"libpq/pqformat.h"
26+
#include"miscadmin.h"
2627
#include"nodes/pg_list.h"
2728
#include"replication/basebackup.h"
2829
#include"replication/walsender.h"
@@ -43,7 +44,7 @@ typedef struct
4344
}basebackup_options;
4445

4546

46-
staticint64sendDir(char*path,intbasepathlen,boolsizeonly);
47+
staticint64sendDir(char*path,intbasepathlen,boolsizeonly,List*tablespaces);
4748
staticint64sendTablespace(char*path,boolsizeonly);
4849
staticboolsendFile(char*readfilename,char*tarfilename,
4950
structstat*statbuf,boolmissing_ok);
@@ -68,6 +69,7 @@ typedef struct
6869
{
6970
char*oid;
7071
char*path;
72+
char*rpath;/* relative path within PGDATA, or NULL */
7173
int64size;
7274
}tablespaceinfo;
7375

@@ -94,6 +96,9 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
9496
XLogRecPtrstartptr;
9597
XLogRecPtrendptr;
9698
char*labelfile;
99+
intdatadirpathlen;
100+
101+
datadirpathlen=strlen(DataDir);
97102

98103
startptr=do_pg_start_backup(opt->label,opt->fastcheckpoint,&labelfile);
99104
SendXlogRecPtrResult(startptr);
@@ -110,6 +115,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
110115
{
111116
charfullpath[MAXPGPATH];
112117
charlinkpath[MAXPGPATH];
118+
char*relpath=NULL;
113119
intrllen;
114120

115121
/* Skip special stuff */
@@ -136,9 +142,20 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
136142
}
137143
linkpath[rllen]='\0';
138144

145+
/*
146+
* Relpath holds the relative path of the tablespace directory
147+
* when it's located within PGDATA, or NULL if it's located
148+
* elsewhere.
149+
*/
150+
if (rllen>datadirpathlen&&
151+
strncmp(linkpath,DataDir,datadirpathlen)==0&&
152+
IS_DIR_SEP(linkpath[datadirpathlen]))
153+
relpath=linkpath+datadirpathlen+1;
154+
139155
ti=palloc(sizeof(tablespaceinfo));
140156
ti->oid=pstrdup(de->d_name);
141157
ti->path=pstrdup(linkpath);
158+
ti->rpath=relpath ?pstrdup(relpath) :NULL;
142159
ti->size=opt->progress ?sendTablespace(fullpath, true) :-1;
143160
tablespaces=lappend(tablespaces,ti);
144161
#else
@@ -155,7 +172,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
155172

156173
/* Add a node for the base directory at the end */
157174
ti=palloc0(sizeof(tablespaceinfo));
158-
ti->size=opt->progress ?sendDir(".",1, true) :-1;
175+
ti->size=opt->progress ?sendDir(".",1, true,tablespaces) :-1;
159176
tablespaces=lappend(tablespaces,ti);
160177

161178
/* Send tablespace header */
@@ -181,7 +198,7 @@ perform_base_backup(basebackup_options *opt, DIR *tblspcdir)
181198
sendFileWithContent(BACKUP_LABEL_FILE,labelfile);
182199

183200
/* ... then the bulk of the files ... */
184-
sendDir(".",1, false);
201+
sendDir(".",1, false,tablespaces);
185202

186203
/* ... and pg_control after everything else. */
187204
if (lstat(XLOG_CONTROL_FILE,&statbuf)!=0)
@@ -571,6 +588,8 @@ sendFileWithContent(const char *filename, const char *content)
571588
* Include the tablespace directory pointed to by 'path' in the output tar
572589
* stream. If 'sizeonly' is true, we just calculate a total length and return
573590
* it, without actually sending anything.
591+
*
592+
* Only used to send auxiliary tablespaces, not PGDATA.
574593
*/
575594
staticint64
576595
sendTablespace(char*path,boolsizeonly)
@@ -605,7 +624,7 @@ sendTablespace(char *path, bool sizeonly)
605624
size=512;/* Size of the header just added */
606625

607626
/* Send all the files in the tablespace version directory */
608-
size+=sendDir(pathbuf,strlen(path),sizeonly);
627+
size+=sendDir(pathbuf,strlen(path),sizeonly,NIL);
609628

610629
returnsize;
611630
}
@@ -614,9 +633,12 @@ sendTablespace(char *path, bool sizeonly)
614633
* Include all files from the given directory in the output tar stream. If
615634
* 'sizeonly' is true, we just calculate a total length and return it, without
616635
* actually sending anything.
636+
*
637+
* Omit any directory in the tablespaces list, to avoid backing up
638+
* tablespaces twice when they were created inside PGDATA.
617639
*/
618640
staticint64
619-
sendDir(char*path,intbasepathlen,boolsizeonly)
641+
sendDir(char*path,intbasepathlen,boolsizeonly,List*tablespaces)
620642
{
621643
DIR*dir;
622644
structdirent*de;
@@ -737,6 +759,9 @@ sendDir(char *path, int basepathlen, bool sizeonly)
737759
}
738760
elseif (S_ISDIR(statbuf.st_mode))
739761
{
762+
boolskip_this_dir= false;
763+
ListCell*lc;
764+
740765
/*
741766
* Store a directory entry in the tar file so we can get the
742767
* permissions right.
@@ -745,8 +770,29 @@ sendDir(char *path, int basepathlen, bool sizeonly)
745770
_tarWriteHeader(pathbuf+basepathlen+1,NULL,&statbuf);
746771
size+=512;/* Size of the header just added */
747772

748-
/* call ourselves recursively for a directory */
749-
size+=sendDir(pathbuf,basepathlen,sizeonly);
773+
/*
774+
* Call ourselves recursively for a directory, unless it happens
775+
* to be a separate tablespace located within PGDATA.
776+
*/
777+
foreach(lc,tablespaces)
778+
{
779+
tablespaceinfo*ti= (tablespaceinfo*)lfirst(lc);
780+
781+
/*
782+
* ti->rpath is the tablespace relative path within PGDATA, or
783+
* NULL if the tablespace has been properly located somewhere
784+
* else.
785+
*
786+
* Skip past the leading "./" in pathbuf when comparing.
787+
*/
788+
if (ti->rpath&&strcmp(ti->rpath,pathbuf+2)==0)
789+
{
790+
skip_this_dir= true;
791+
break;
792+
}
793+
}
794+
if (!skip_this_dir)
795+
size+=sendDir(pathbuf,basepathlen,sizeonly,tablespaces);
750796
}
751797
elseif (S_ISREG(statbuf.st_mode))
752798
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp