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

Commit9083353

Browse files
committed
pg_basebackup: Clean created directories on failure
Like initdb, clean up created data and xlog directories, unless the new-n/--noclean option is specified.Tablespace directories are not cleaned up, but a message is writtenabout that.Reviewed-by: Masahiko Sawada <sawada.mshk@gmail.com>
1 parent63c1a87 commit9083353

File tree

3 files changed

+119
-7
lines changed

3 files changed

+119
-7
lines changed

‎doc/src/sgml/ref/pg_basebackup.sgml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,24 @@ PostgreSQL documentation
398398
</listitem>
399399
</varlistentry>
400400

401+
<varlistentry>
402+
<term><option>-n</option></term>
403+
<term><option>--noclean</option></term>
404+
<listitem>
405+
<para>
406+
By default, when <command>pg_basebackup</command> aborts with an
407+
error, it removes any directories it might have created before
408+
discovering that it cannot finish the job (for example, data directory
409+
and transaction log directory). This option inhibits tidying-up and is
410+
thus useful for debugging.
411+
</para>
412+
413+
<para>
414+
Note that tablespace directories are not cleaned up either way.
415+
</para>
416+
</listitem>
417+
</varlistentry>
418+
401419
<varlistentry>
402420
<term><option>-P</option></term>
403421
<term><option>--progress</option></term>

‎src/bin/pg_basebackup/pg_basebackup.c

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static TablespaceList tablespace_dirs = {NULL, NULL};
5858
staticchar*xlog_dir="";
5959
staticcharformat='p';/* p(lain)/t(ar) */
6060
staticchar*label="pg_basebackup base backup";
61+
staticboolnoclean= false;
6162
staticboolshowprogress= false;
6263
staticintverbose=0;
6364
staticintcompresslevel=0;
@@ -69,6 +70,13 @@ static intstandby_message_timeout = 10 * 1000;/* 10 sec = default */
6970
staticpg_time_tlast_progress_report=0;
7071
staticint32maxrate=0;/* no limit by default */
7172

73+
staticboolsuccess= false;
74+
staticboolmade_new_pgdata= false;
75+
staticboolfound_existing_pgdata= false;
76+
staticboolmade_new_xlogdir= false;
77+
staticboolfound_existing_xlogdir= false;
78+
staticboolmade_tablespace_dirs= false;
79+
staticboolfound_tablespace_dirs= false;
7280

7381
/* Progress counters */
7482
staticuint64totalsize;
@@ -82,6 +90,7 @@ static intbgpipe[2] = {-1, -1};
8290

8391
/* Handle to child process */
8492
staticpid_tbgchild=-1;
93+
staticboolin_log_streamer= false;
8594

8695
/* End position for xlog streaming, empty string if unknown yet */
8796
staticXLogRecPtrxlogendptr;
@@ -98,7 +107,7 @@ static PQExpBuffer recoveryconfcontents = NULL;
98107
/* Function headers */
99108
staticvoidusage(void);
100109
staticvoiddisconnect_and_exit(intcode);
101-
staticvoidverify_dir_is_empty_or_create(char*dirname);
110+
staticvoidverify_dir_is_empty_or_create(char*dirname,bool*created,bool*found);
102111
staticvoidprogress_report(inttablespacenum,constchar*filename,boolforce);
103112

104113
staticvoidReceiveTarFile(PGconn*conn,PGresult*res,intrownum);
@@ -114,6 +123,69 @@ static const char *get_tablespace_mapping(const char *dir);
114123
staticvoidtablespace_list_append(constchar*arg);
115124

116125

126+
staticvoid
127+
cleanup_directories_atexit(void)
128+
{
129+
if (success||in_log_streamer)
130+
return;
131+
132+
if (!noclean)
133+
{
134+
if (made_new_pgdata)
135+
{
136+
fprintf(stderr,_("%s: removing data directory \"%s\"\n"),
137+
progname,basedir);
138+
if (!rmtree(basedir, true))
139+
fprintf(stderr,_("%s: failed to remove data directory\n"),
140+
progname);
141+
}
142+
elseif (found_existing_pgdata)
143+
{
144+
fprintf(stderr,
145+
_("%s: removing contents of data directory \"%s\"\n"),
146+
progname,basedir);
147+
if (!rmtree(basedir, false))
148+
fprintf(stderr,_("%s: failed to remove contents of data directory\n"),
149+
progname);
150+
}
151+
152+
if (made_new_xlogdir)
153+
{
154+
fprintf(stderr,_("%s: removing transaction log directory \"%s\"\n"),
155+
progname,xlog_dir);
156+
if (!rmtree(xlog_dir, true))
157+
fprintf(stderr,_("%s: failed to remove transaction log directory\n"),
158+
progname);
159+
}
160+
elseif (found_existing_xlogdir)
161+
{
162+
fprintf(stderr,
163+
_("%s: removing contents of transaction log directory \"%s\"\n"),
164+
progname,xlog_dir);
165+
if (!rmtree(xlog_dir, false))
166+
fprintf(stderr,_("%s: failed to remove contents of transaction log directory\n"),
167+
progname);
168+
}
169+
}
170+
else
171+
{
172+
if (made_new_pgdata||found_existing_pgdata)
173+
fprintf(stderr,
174+
_("%s: data directory \"%s\" not removed at user's request\n"),
175+
progname,basedir);
176+
177+
if (made_new_xlogdir||found_existing_xlogdir)
178+
fprintf(stderr,
179+
_("%s: transaction log directory \"%s\" not removed at user's request\n"),
180+
progname,xlog_dir);
181+
}
182+
183+
if (made_tablespace_dirs||found_tablespace_dirs)
184+
fprintf(stderr,
185+
_("%s: changes to tablespace directories will not be undone"),
186+
progname);
187+
}
188+
117189
staticvoid
118190
disconnect_and_exit(intcode)
119191
{
@@ -253,6 +325,7 @@ usage(void)
253325
printf(_(" -c, --checkpoint=fast|spread\n"
254326
" set fast or spread checkpointing\n"));
255327
printf(_(" -l, --label=LABEL set backup label\n"));
328+
printf(_(" -n, --noclean do not clean up after errors\n"));
256329
printf(_(" -P, --progress show progress information\n"));
257330
printf(_(" -v, --verbose output verbose messages\n"));
258331
printf(_(" -V, --version output version information, then exit\n"));
@@ -375,6 +448,8 @@ LogStreamerMain(logstreamer_param *param)
375448
{
376449
StreamCtlstream;
377450

451+
in_log_streamer= true;
452+
378453
MemSet(&stream,0,sizeof(stream));
379454
stream.startpos=param->startptr;
380455
stream.timeline=param->timeline;
@@ -501,7 +576,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
501576
* be give and the process ended.
502577
*/
503578
staticvoid
504-
verify_dir_is_empty_or_create(char*dirname)
579+
verify_dir_is_empty_or_create(char*dirname,bool*created,bool*found)
505580
{
506581
switch (pg_check_dir(dirname))
507582
{
@@ -517,12 +592,16 @@ verify_dir_is_empty_or_create(char *dirname)
517592
progname,dirname,strerror(errno));
518593
disconnect_and_exit(1);
519594
}
595+
if (created)
596+
*created= true;
520597
return;
521598
case1:
522599

523600
/*
524601
* Exists, empty
525602
*/
603+
if (found)
604+
*found= true;
526605
return;
527606
case2:
528607
case3:
@@ -1683,7 +1762,7 @@ BaseBackup(void)
16831762
{
16841763
char*path= (char*)get_tablespace_mapping(PQgetvalue(res,i,1));
16851764

1686-
verify_dir_is_empty_or_create(path);
1765+
verify_dir_is_empty_or_create(path,&made_tablespace_dirs,&found_tablespace_dirs);
16871766
}
16881767
}
16891768

@@ -1892,6 +1971,7 @@ main(int argc, char **argv)
18921971
{"gzip",no_argument,NULL,'z'},
18931972
{"compress",required_argument,NULL,'Z'},
18941973
{"label",required_argument,NULL,'l'},
1974+
{"noclean",no_argument,NULL,'n'},
18951975
{"dbname",required_argument,NULL,'d'},
18961976
{"host",required_argument,NULL,'h'},
18971977
{"port",required_argument,NULL,'p'},
@@ -1926,7 +2006,9 @@ main(int argc, char **argv)
19262006
}
19272007
}
19282008

1929-
while ((c=getopt_long(argc,argv,"D:F:r:RT:xX:l:zZ:d:c:h:p:U:s:S:wWvP",
2009+
atexit(cleanup_directories_atexit);
2010+
2011+
while ((c=getopt_long(argc,argv,"D:F:r:RT:xX:l:nzZ:d:c:h:p:U:s:S:wWvP",
19302012
long_options,&option_index))!=-1)
19312013
{
19322014
switch (c)
@@ -2001,6 +2083,9 @@ main(int argc, char **argv)
20012083
case'l':
20022084
label=pg_strdup(optarg);
20032085
break;
2086+
case'n':
2087+
noclean= true;
2088+
break;
20042089
case'z':
20052090
#ifdefHAVE_LIBZ
20062091
compresslevel=Z_DEFAULT_COMPRESSION;
@@ -2170,14 +2255,14 @@ main(int argc, char **argv)
21702255
* unless we are writing to stdout.
21712256
*/
21722257
if (format=='p'||strcmp(basedir,"-")!=0)
2173-
verify_dir_is_empty_or_create(basedir);
2258+
verify_dir_is_empty_or_create(basedir,&made_new_pgdata,&found_existing_pgdata);
21742259

21752260
/* Create transaction log symlink, if required */
21762261
if (strcmp(xlog_dir,"")!=0)
21772262
{
21782263
char*linkloc;
21792264

2180-
verify_dir_is_empty_or_create(xlog_dir);
2265+
verify_dir_is_empty_or_create(xlog_dir,&made_new_xlogdir,&found_existing_xlogdir);
21812266

21822267
/* form name of the place where the symlink must go */
21832268
linkloc=psprintf("%s/pg_xlog",basedir);
@@ -2198,5 +2283,6 @@ main(int argc, char **argv)
21982283

21992284
BaseBackup();
22002285

2286+
success= true;
22012287
return0;
22022288
}

‎src/bin/pg_basebackup/t/010_pg_basebackup.pl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use Config;
55
use PostgresNode;
66
use TestLib;
7-
use Test::Moretests=>51;
7+
use Test::Moretests=>54;
88

99
program_help_ok('pg_basebackup');
1010
program_version_ok('pg_basebackup');
@@ -40,6 +40,14 @@
4040
['pg_basebackup','-D',"$tempdir/backup" ],
4141
'pg_basebackup fails because of WAL configuration');
4242

43+
ok(!-d"$tempdir/backup",'backup directory was cleaned up');
44+
45+
$node->command_fails(
46+
['pg_basebackup','-D',"$tempdir/backup",'-n' ],
47+
'failing run with noclean option');
48+
49+
ok(-d"$tempdir/backup",'backup directory was created and left behind');
50+
4351
open CONF,">>$pgdata/postgresql.conf";
4452
print CONF"max_replication_slots = 10\n";
4553
print CONF"max_wal_senders = 10\n";

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp