30#include "catalog/pg_tablespace_d.h"
42#define SH_PREFIX filehash
43#define SH_ELEMENT_TYPE file_entry_t
44#define SH_KEY_TYPE const char *
46#define SH_HASH_KEY(tb, key) hash_string(key)
47#define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0)
48#define SH_SCOPE static inline
49#define SH_RAW_ALLOCATOR pg_malloc0
54#define FILEHASH_INITIAL_SIZE 1000
74#define SH_PREFIX keepwal
75#define SH_ELEMENT_TYPE keepwal_entry
76#define SH_KEY_TYPE const char *
78#define SH_HASH_KEY(tb, key) hash_string(key)
79#define SH_EQUAL(tb, a, b) (strcmp(a, b) == 0)
80#define SH_SCOPE static inline
81#define SH_RAW_ALLOCATOR pg_malloc0
86#define KEEPWAL_INITIAL_SIZE 1000
161 {
"postgresql.auto.conf.tmp",
false},
164 {
"current_logfiles.tmp",
false},
168 {
"pg_internal.init",
true},
175 {
"backup_label",
false},
176 {
"tablespace_map",
false},
184 {
"backup_manifest",
false},
186 {
"postmaster.pid",
false},
187 {
"postmaster.opts",
false},
209 entry = filehash_insert(
filehash, path, &found);
236 return filehash_lookup(
filehash, path);
259 entry = keepwal_insert(
keepwal, path, &found);
269 return keepwal_lookup(
keepwal, path) != NULL;
281 const char *link_target)
298 pg_fatal(
"data file \"%s\" in source is not a regular file", path);
303 pg_fatal(
"duplicate source file \"%s\"", path);
317 const char *link_target)
336 pg_fatal(
"duplicate source file \"%s\"", path);
361 segno = blkno / RELSEG_SIZE;
362 blkno_inseg = blkno % RELSEG_SIZE;
391 pg_fatal(
"unexpected page modification for non-regular file \"%s\"",
398 end_offset = (blkno_inseg + 1) * BLCKSZ;
399 if (end_offset <= entry->source_size && end_offset <= entry->target_size)
441 pg_log_debug(
"entry \"%s\" excluded from source file list",
444 pg_log_debug(
"entry \"%s\" excluded from target file list",
456 snprintf(localpath,
sizeof(localpath),
"%s/",
458 if (strstr(path, localpath) == path)
461 pg_log_debug(
"entry \"%s\" excluded from source file list",
464 pg_log_debug(
"entry \"%s\" excluded from target file list",
576 if (strncmp(
"pg_wal/", path, 7) == 0)
618 nmatch = sscanf(path,
"global/%u.%u", &rlocator.
relNumber, &segNo);
619 if (nmatch == 1 || nmatch == 2)
621 rlocator.
spcOid = GLOBALTABLESPACE_OID;
627 nmatch = sscanf(path,
"base/%u/%u.%u",
629 if (nmatch == 2 || nmatch == 3)
631 rlocator.
spcOid = DEFAULTTABLESPACE_OID;
639 if (nmatch == 3 || nmatch == 4)
654 if (strcmp(check_path, path) != 0)
700 if (
fa->action >
fb->action)
702 if (
fa->action <
fb->action)
706 return strcmp(
fb->path,
fa->path);
708 return strcmp(
fa->path,
fb->path);
720 size_t source_size,
size_t target_size)
738 if (file_segno < last_common_segno &&
739 source_size == target_size)
751 const char *path = entry->
path;
761 if (strstr(path,
".DS_Store") != NULL)
805 pg_log_debug(
"Not removing file \"%s\" because it is required for recovery", path);
828 pg_fatal(
"file \"%s\" is of different type in source and target", entry->
path);
909 pg_fatal(
"unknown file type for \"%s\"", path);
914 pg_fatal(
"could not decide what to do with file \"%s\"", path);
927 filehash_iterator it;
931 filehash_start_iterate(
filehash, &it);
932 while ((entry = filehash_iterate(
filehash, &it)) != NULL)
944 filehash_start_iterate(
filehash, &it);
946 while ((entry = filehash_iterate(
filehash, &it)) != NULL)
bool datapagemap_next(datapagemap_iterator_t *iter, BlockNumber *blkno)
void datapagemap_print(datapagemap_t *map)
datapagemap_iterator_t * datapagemap_iterate(datapagemap_t *map)
void datapagemap_add(datapagemap_t *map, BlockNumber blkno)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
#define PG_TEMP_FILES_DIR
#define PG_TEMP_FILE_PREFIX
static const struct exclude_list_item excludeFiles[]
struct keepwal_entry keepwal_entry
static bool keepwal_entry_exists(const char *path)
static const char * action_to_str(file_action_t action)
void process_source_file(const char *path, file_type_t type, size_t size, const char *link_target)
static const char *const excludeDirContents[]
void print_filemap(filemap_t *filemap)
static char * datasegpath(RelFileLocator rlocator, ForkNumber forknum, BlockNumber segno)
static file_action_t decide_file_action(file_entry_t *entry, XLogSegNo last_common_segno)
static filehash_hash * filehash
void process_target_file(const char *path, file_type_t type, size_t size, const char *link_target)
void process_target_wal_block_change(ForkNumber forknum, RelFileLocator rlocator, BlockNumber blkno)
void keepwal_add_entry(const char *path)
static file_action_t decide_wal_file_action(const char *fname, XLogSegNo last_common_segno, size_t source_size, size_t target_size)
static keepwal_hash * keepwal
static file_entry_t * lookup_filehash_entry(const char *path)
#define KEEPWAL_INITIAL_SIZE
static file_entry_t * insert_filehash_entry(const char *path)
static bool check_file_excluded(const char *path, bool is_source)
#define FILEHASH_INITIAL_SIZE
static int final_filemap_cmp(const void *a, const void *b)
void calculate_totals(filemap_t *filemap)
filemap_t * decide_file_actions(XLogSegNo last_common_segno)
static file_content_type_t getFileContentType(const char *path)
@ FILE_CONTENT_TYPE_OTHER
@ FILE_CONTENT_TYPE_RELATION
Assert(PointerIsAligned(start, uint64))
#define pg_log_debug(...)
char * pstrdup(const char *in)
void pfree(void *pointer)
char * last_dir_separator(const char *filename)
#define qsort(a, b, c, d)
char * psprintf(const char *fmt,...)
#define InvalidRelFileNumber
#define relpathperm(rlocator, forknum)
#define TABLESPACE_VERSION_DIRECTORY
bool pg_str_endswith(const char *str, const char *end)
char str[REL_PATH_STR_MAXLEN+1]
datapagemap_t target_pages_to_overwrite
char * source_link_target
file_content_type_t content_type
char * target_link_target
file_entry_t * entries[FLEXIBLE_ARRAY_MEMBER]
#define XLOG_CONTROL_FILE
static bool IsXLogFileName(const char *fname)
static void XLogFromFileName(const char *fname, TimeLineID *tli, XLogSegNo *logSegNo, int wal_segsz_bytes)