@@ -50,7 +50,8 @@ static int pre_sync_fname(const char *fname, bool isdir);
50
50
#endif
51
51
static void walkdir (const char * path ,
52
52
int (* action ) (const char * fname , bool isdir ),
53
- bool process_symlinks );
53
+ bool process_symlinks ,
54
+ const char * exclude_dir );
54
55
55
56
#ifdef HAVE_SYNCFS
56
57
@@ -93,11 +94,15 @@ do_syncfs(const char *path)
93
94
* syncing, and might not have privileges to write at all.
94
95
*
95
96
* serverVersion indicates the version of the server to be sync'd.
97
+ *
98
+ * If sync_data_files is false, this function skips syncing "base/" and any
99
+ * other tablespace directories.
96
100
*/
97
101
void
98
102
sync_pgdata (const char * pg_data ,
99
103
int serverVersion ,
100
- DataDirSyncMethod sync_method )
104
+ DataDirSyncMethod sync_method ,
105
+ bool sync_data_files )
101
106
{
102
107
bool xlog_is_symlink ;
103
108
char pg_wal [MAXPGPATH ];
@@ -147,30 +152,33 @@ sync_pgdata(const char *pg_data,
147
152
do_syncfs (pg_data );
148
153
149
154
/* If any tablespaces are configured, sync each of those. */
150
- dir = opendir (pg_tblspc );
151
- if (dir == NULL )
152
- pg_log_error ("could not open directory \"%s\": %m" ,
153
- pg_tblspc );
154
- else
155
+ if (sync_data_files )
155
156
{
156
- while (errno = 0 , (de = readdir (dir )) != NULL )
157
+ dir = opendir (pg_tblspc );
158
+ if (dir == NULL )
159
+ pg_log_error ("could not open directory \"%s\": %m" ,
160
+ pg_tblspc );
161
+ else
157
162
{
158
- char subpath [MAXPGPATH * 2 ];
163
+ while (errno = 0 , (de = readdir (dir )) != NULL )
164
+ {
165
+ char subpath [MAXPGPATH * 2 ];
159
166
160
- if (strcmp (de -> d_name , "." ) == 0 ||
161
- strcmp (de -> d_name , ".." ) == 0 )
162
- continue ;
167
+ if (strcmp (de -> d_name , "." ) == 0 ||
168
+ strcmp (de -> d_name , ".." ) == 0 )
169
+ continue ;
163
170
164
- snprintf (subpath , sizeof (subpath ), "%s/%s" ,
165
- pg_tblspc , de -> d_name );
166
- do_syncfs (subpath );
167
- }
171
+ snprintf (subpath , sizeof (subpath ), "%s/%s" ,
172
+ pg_tblspc , de -> d_name );
173
+ do_syncfs (subpath );
174
+ }
168
175
169
- if (errno )
170
- pg_log_error ("could not read directory \"%s\": %m" ,
171
- pg_tblspc );
176
+ if (errno )
177
+ pg_log_error ("could not read directory \"%s\": %m" ,
178
+ pg_tblspc );
172
179
173
- (void ) closedir (dir );
180
+ (void ) closedir (dir );
181
+ }
174
182
}
175
183
176
184
/* If pg_wal is a symlink, process that too. */
@@ -182,15 +190,21 @@ sync_pgdata(const char *pg_data,
182
190
183
191
case DATA_DIR_SYNC_METHOD_FSYNC :
184
192
{
193
+ char * exclude_dir = NULL ;
194
+
195
+ if (!sync_data_files )
196
+ exclude_dir = psprintf ("%s/base" , pg_data );
197
+
185
198
/*
186
199
* If possible, hint to the kernel that we're soon going to
187
200
* fsync the data directory and its contents.
188
201
*/
189
202
#ifdef PG_FLUSH_DATA_WORKS
190
- walkdir (pg_data , pre_sync_fname , false);
203
+ walkdir (pg_data , pre_sync_fname , false, exclude_dir );
191
204
if (xlog_is_symlink )
192
- walkdir (pg_wal , pre_sync_fname , false);
193
- walkdir (pg_tblspc , pre_sync_fname , true);
205
+ walkdir (pg_wal , pre_sync_fname , false, NULL );
206
+ if (sync_data_files )
207
+ walkdir (pg_tblspc , pre_sync_fname , true, NULL );
194
208
#endif
195
209
196
210
/*
@@ -203,10 +217,14 @@ sync_pgdata(const char *pg_data,
203
217
* get fsync'd twice. That's not an expected case so we don't
204
218
* worry about optimizing it.
205
219
*/
206
- walkdir (pg_data , fsync_fname , false);
220
+ walkdir (pg_data , fsync_fname , false, exclude_dir );
207
221
if (xlog_is_symlink )
208
- walkdir (pg_wal , fsync_fname , false);
209
- walkdir (pg_tblspc , fsync_fname , true);
222
+ walkdir (pg_wal , fsync_fname , false, NULL );
223
+ if (sync_data_files )
224
+ walkdir (pg_tblspc , fsync_fname , true, NULL );
225
+
226
+ if (exclude_dir )
227
+ pfree (exclude_dir );
210
228
}
211
229
break ;
212
230
}
@@ -245,10 +263,10 @@ sync_dir_recurse(const char *dir, DataDirSyncMethod sync_method)
245
263
* fsync the data directory and its contents.
246
264
*/
247
265
#ifdef PG_FLUSH_DATA_WORKS
248
- walkdir (dir , pre_sync_fname , false);
266
+ walkdir (dir , pre_sync_fname , false, NULL );
249
267
#endif
250
268
251
- walkdir (dir , fsync_fname , false);
269
+ walkdir (dir , fsync_fname , false, NULL );
252
270
}
253
271
break ;
254
272
}
@@ -264,18 +282,25 @@ sync_dir_recurse(const char *dir, DataDirSyncMethod sync_method)
264
282
* ignored in subdirectories, ie we intentionally don't pass down the
265
283
* process_symlinks flag to recursive calls.
266
284
*
285
+ * If exclude_dir is not NULL, it specifies a directory path to skip
286
+ * processing.
287
+ *
267
288
* Errors are reported but not considered fatal.
268
289
*
269
290
* See also walkdir in fd.c, which is a backend version of this logic.
270
291
*/
271
292
static void
272
293
walkdir (const char * path ,
273
294
int (* action ) (const char * fname , bool isdir ),
274
- bool process_symlinks )
295
+ bool process_symlinks ,
296
+ const char * exclude_dir )
275
297
{
276
298
DIR * dir ;
277
299
struct dirent * de ;
278
300
301
+ if (exclude_dir && strcmp (exclude_dir , path ) == 0 )
302
+ return ;
303
+
279
304
dir = opendir (path );
280
305
if (dir == NULL )
281
306
{
@@ -299,7 +324,7 @@ walkdir(const char *path,
299
324
(* action ) (subpath , false);
300
325
break ;
301
326
case PGFILETYPE_DIR :
302
- walkdir (subpath , action , false);
327
+ walkdir (subpath , action , false, exclude_dir );
303
328
break ;
304
329
default :
305
330
0 commit comments