@@ -31,6 +31,83 @@ static char *datasegpath(RelFileNode rnode, ForkNumber forknum,
3131static int path_cmp (const void * a , const void * b );
3232static int final_filemap_cmp (const void * a , const void * b );
3333static void filemap_list_to_array (filemap_t * map );
34+ static bool check_file_excluded (const char * path , const char * type );
35+
36+ /*
37+ * The contents of these directories are removed or recreated during server
38+ * start so they are not included in data processed by pg_rewind.
39+ *
40+ * Note: those lists should be kept in sync with what basebackup.c provides.
41+ * Some of the values, contrary to what basebackup.c uses, are hardcoded as
42+ * they are defined in backend-only headers. So this list is maintained
43+ * with a best effort in mind.
44+ */
45+ static const char * excludeDirContents [] =
46+ {
47+ /*
48+ * Skip temporary statistics files. PG_STAT_TMP_DIR must be skipped even
49+ * when stats_temp_directory is set because PGSS_TEXT_FILE is always
50+ * created there.
51+ */
52+ "pg_stat_tmp" , /* defined as PG_STAT_TMP_DIR */
53+
54+ /*
55+ * It is generally not useful to backup the contents of this directory
56+ * even if the intention is to restore to another master. See backup.sgml
57+ * for a more detailed description.
58+ */
59+ "pg_replslot" ,
60+
61+ /* Contents removed on startup, see dsm_cleanup_for_mmap(). */
62+ "pg_dynshmem" , /* defined as PG_DYNSHMEM_DIR */
63+
64+ /* Contents removed on startup, see AsyncShmemInit(). */
65+ "pg_notify" ,
66+
67+ /*
68+ * Old contents are loaded for possible debugging but are not required for
69+ * normal operation, see OldSerXidInit().
70+ */
71+ "pg_serial" ,
72+
73+ /* Contents removed on startup, see DeleteAllExportedSnapshotFiles(). */
74+ "pg_snapshots" ,
75+
76+ /* Contents zeroed on startup, see StartupSUBTRANS(). */
77+ "pg_subtrans" ,
78+
79+ /* end of list */
80+ NULL
81+ };
82+
83+ /*
84+ * List of files excluded from filemap processing.
85+ */
86+ static const char * excludeFiles [] =
87+ {
88+ /* Skip auto conf temporary file. */
89+ "postgresql.auto.conf.tmp" , /* defined as PG_AUTOCONF_FILENAME */
90+
91+ /* Skip current log file temporary file */
92+ "current_logfiles.tmp" , /* defined as LOG_METAINFO_DATAFILE_TMP */
93+
94+ /* Skip relation cache because it is rebuilt on startup */
95+ "pg_internal.init" , /* defined as RELCACHE_INIT_FILENAME */
96+
97+ /*
98+ * If there's a backup_label or tablespace_map file, it belongs to a
99+ * backup started by the user with pg_start_backup(). It is *not* correct
100+ * for this backup. Our backup_label is written later on separately.
101+ */
102+ "backup_label" , /* defined as BACKUP_LABEL_FILE */
103+ "tablespace_map" , /* defined as TABLESPACE_MAP */
104+
105+ "postmaster.pid" ,
106+ "postmaster.opts" ,
107+
108+ /* end of list */
109+ NULL
110+ };
34111
35112/*
36113 * Create a new file map (stored in the global pointer "filemap").
@@ -71,11 +148,8 @@ process_source_file(const char *path, file_type_t type, size_t newsize,
71148
72149 Assert (map -> array == NULL );
73150
74- /*
75- * Completely ignore some special files in source and destination.
76- */
77- if (strcmp (path , "postmaster.pid" ) == 0 ||
78- strcmp (path , "postmaster.opts" ) == 0 )
151+ /* ignore any path matching the exclusion filters */
152+ if (check_file_excluded (path , "source" ))
79153 return ;
80154
81155 /*
@@ -260,6 +334,14 @@ process_target_file(const char *path, file_type_t type, size_t oldsize,
260334 filemap_t * map = filemap ;
261335 file_entry_t * entry ;
262336
337+ /*
338+ * Ignore any path matching the exclusion filters. This is not actually
339+ * mandatory for target files, but this does not hurt and let's be
340+ * consistent with the source processing.
341+ */
342+ if (check_file_excluded (path , "target" ))
343+ return ;
344+
263345 snprintf (localpath , sizeof (localpath ), "%s/%s" , datadir_target , path );
264346 if (lstat (localpath , & statbuf ) < 0 )
265347 {
@@ -286,13 +368,6 @@ process_target_file(const char *path, file_type_t type, size_t oldsize,
286368 qsort (map -> array , map -> narray , sizeof (file_entry_t * ), path_cmp );
287369 }
288370
289- /*
290- * Completely ignore some special files
291- */
292- if (strcmp (path , "postmaster.pid" ) == 0 ||
293- strcmp (path , "postmaster.opts" ) == 0 )
294- return ;
295-
296371 /*
297372 * Like in process_source_file, pretend that xlog is always a directory.
298373 */
@@ -412,6 +487,51 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
412487 }
413488}
414489
490+ /*
491+ * Is this the path of file that pg_rewind can skip copying?
492+ */
493+ static bool
494+ check_file_excluded (const char * path , const char * type )
495+ {
496+ char localpath [MAXPGPATH ];
497+ int excludeIdx ;
498+ const char * filename ;
499+
500+ /* check individual files... */
501+ for (excludeIdx = 0 ; excludeFiles [excludeIdx ] != NULL ; excludeIdx ++ )
502+ {
503+ filename = last_dir_separator (path );
504+ if (filename == NULL )
505+ filename = path ;
506+ else
507+ filename ++ ;
508+ if (strcmp (filename , excludeFiles [excludeIdx ]) == 0 )
509+ {
510+ pg_log (PG_DEBUG , "entry \"%s\" excluded from %s file list\n" ,
511+ path , type );
512+ return true;
513+ }
514+ }
515+
516+ /*
517+ * ... And check some directories. Note that this includes any contents
518+ * within the directories themselves.
519+ */
520+ for (excludeIdx = 0 ; excludeDirContents [excludeIdx ] != NULL ; excludeIdx ++ )
521+ {
522+ snprintf (localpath , sizeof (localpath ), "%s/" ,
523+ excludeDirContents [excludeIdx ]);
524+ if (strstr (path , localpath ) == path )
525+ {
526+ pg_log (PG_DEBUG , "entry \"%s\" excluded from %s file list\n" ,
527+ path , type );
528+ return true;
529+ }
530+ }
531+
532+ return false;
533+ }
534+
415535/*
416536 * Convert the linked list of entries in map->first/last to the array,
417537 * map->array.
0 commit comments