@@ -58,6 +58,7 @@ static TablespaceList tablespace_dirs = {NULL, NULL};
58
58
static char * xlog_dir = "" ;
59
59
static char format = 'p' ; /* p(lain)/t(ar) */
60
60
static char * label = "pg_basebackup base backup" ;
61
+ static bool noclean = false;
61
62
static bool showprogress = false;
62
63
static int verbose = 0 ;
63
64
static int compresslevel = 0 ;
@@ -69,6 +70,13 @@ static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
69
70
static pg_time_t last_progress_report = 0 ;
70
71
static int32 maxrate = 0 ; /* no limit by default */
71
72
73
+ static bool success = false;
74
+ static bool made_new_pgdata = false;
75
+ static bool found_existing_pgdata = false;
76
+ static bool made_new_xlogdir = false;
77
+ static bool found_existing_xlogdir = false;
78
+ static bool made_tablespace_dirs = false;
79
+ static bool found_tablespace_dirs = false;
72
80
73
81
/* Progress counters */
74
82
static uint64 totalsize ;
@@ -82,6 +90,7 @@ static int bgpipe[2] = {-1, -1};
82
90
83
91
/* Handle to child process */
84
92
static pid_t bgchild = -1 ;
93
+ static bool in_log_streamer = false;
85
94
86
95
/* End position for xlog streaming, empty string if unknown yet */
87
96
static XLogRecPtr xlogendptr ;
@@ -98,7 +107,7 @@ static PQExpBuffer recoveryconfcontents = NULL;
98
107
/* Function headers */
99
108
static void usage (void );
100
109
static void disconnect_and_exit (int code );
101
- static void verify_dir_is_empty_or_create (char * dirname );
110
+ static void verify_dir_is_empty_or_create (char * dirname , bool * created , bool * found );
102
111
static void progress_report (int tablespacenum , const char * filename , bool force );
103
112
104
113
static void ReceiveTarFile (PGconn * conn , PGresult * res , int rownum );
@@ -114,6 +123,69 @@ static const char *get_tablespace_mapping(const char *dir);
114
123
static void tablespace_list_append (const char * arg );
115
124
116
125
126
+ static void
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
+ else if (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
+ else if (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
+
117
189
static void
118
190
disconnect_and_exit (int code )
119
191
{
@@ -253,6 +325,7 @@ usage(void)
253
325
printf (_ (" -c, --checkpoint=fast|spread\n"
254
326
" set fast or spread checkpointing\n" ));
255
327
printf (_ (" -l, --label=LABEL set backup label\n" ));
328
+ printf (_ (" -n, --noclean do not clean up after errors\n" ));
256
329
printf (_ (" -P, --progress show progress information\n" ));
257
330
printf (_ (" -v, --verbose output verbose messages\n" ));
258
331
printf (_ (" -V, --version output version information, then exit\n" ));
@@ -375,6 +448,8 @@ LogStreamerMain(logstreamer_param *param)
375
448
{
376
449
StreamCtl stream ;
377
450
451
+ in_log_streamer = true;
452
+
378
453
MemSet (& stream , 0 , sizeof (stream ));
379
454
stream .startpos = param -> startptr ;
380
455
stream .timeline = param -> timeline ;
@@ -501,7 +576,7 @@ StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
501
576
* be give and the process ended.
502
577
*/
503
578
static void
504
- verify_dir_is_empty_or_create (char * dirname )
579
+ verify_dir_is_empty_or_create (char * dirname , bool * created , bool * found )
505
580
{
506
581
switch (pg_check_dir (dirname ))
507
582
{
@@ -517,12 +592,16 @@ verify_dir_is_empty_or_create(char *dirname)
517
592
progname , dirname , strerror (errno ));
518
593
disconnect_and_exit (1 );
519
594
}
595
+ if (created )
596
+ * created = true;
520
597
return ;
521
598
case 1 :
522
599
523
600
/*
524
601
* Exists, empty
525
602
*/
603
+ if (found )
604
+ * found = true;
526
605
return ;
527
606
case 2 :
528
607
case 3 :
@@ -1683,7 +1762,7 @@ BaseBackup(void)
1683
1762
{
1684
1763
char * path = (char * ) get_tablespace_mapping (PQgetvalue (res , i , 1 ));
1685
1764
1686
- verify_dir_is_empty_or_create (path );
1765
+ verify_dir_is_empty_or_create (path , & made_tablespace_dirs , & found_tablespace_dirs );
1687
1766
}
1688
1767
}
1689
1768
@@ -1892,6 +1971,7 @@ main(int argc, char **argv)
1892
1971
{"gzip" , no_argument , NULL , 'z' },
1893
1972
{"compress" , required_argument , NULL , 'Z' },
1894
1973
{"label" , required_argument , NULL , 'l' },
1974
+ {"noclean" , no_argument , NULL , 'n' },
1895
1975
{"dbname" , required_argument , NULL , 'd' },
1896
1976
{"host" , required_argument , NULL , 'h' },
1897
1977
{"port" , required_argument , NULL , 'p' },
@@ -1926,7 +2006,9 @@ main(int argc, char **argv)
1926
2006
}
1927
2007
}
1928
2008
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" ,
1930
2012
long_options , & option_index )) != -1 )
1931
2013
{
1932
2014
switch (c )
@@ -2001,6 +2083,9 @@ main(int argc, char **argv)
2001
2083
case 'l' :
2002
2084
label = pg_strdup (optarg );
2003
2085
break ;
2086
+ case 'n' :
2087
+ noclean = true;
2088
+ break ;
2004
2089
case 'z' :
2005
2090
#ifdef HAVE_LIBZ
2006
2091
compresslevel = Z_DEFAULT_COMPRESSION ;
@@ -2170,14 +2255,14 @@ main(int argc, char **argv)
2170
2255
* unless we are writing to stdout.
2171
2256
*/
2172
2257
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 );
2174
2259
2175
2260
/* Create transaction log symlink, if required */
2176
2261
if (strcmp (xlog_dir , "" ) != 0 )
2177
2262
{
2178
2263
char * linkloc ;
2179
2264
2180
- verify_dir_is_empty_or_create (xlog_dir );
2265
+ verify_dir_is_empty_or_create (xlog_dir , & made_new_xlogdir , & found_existing_xlogdir );
2181
2266
2182
2267
/* form name of the place where the symlink must go */
2183
2268
linkloc = psprintf ("%s/pg_xlog" , basedir );
@@ -2198,5 +2283,6 @@ main(int argc, char **argv)
2198
2283
2199
2284
BaseBackup ();
2200
2285
2286
+ success = true;
2201
2287
return 0 ;
2202
2288
}
0 commit comments