diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bin/pg_rewind/filemap.c | 60 | ||||
| -rw-r--r-- | src/bin/pg_rewind/filemap.h | 9 | ||||
| -rw-r--r-- | src/tools/pgindent/typedefs.list | 1 | 
3 files changed, 48 insertions, 22 deletions
| diff --git a/src/bin/pg_rewind/filemap.c b/src/bin/pg_rewind/filemap.c index c933871ca9f..00f5d60d620 100644 --- a/src/bin/pg_rewind/filemap.c +++ b/src/bin/pg_rewind/filemap.c @@ -55,7 +55,7 @@  static filehash_hash *filehash; -static bool isRelDataFile(const char *path); +static file_content_type_t getFileContentType(const char *path);  static char *datasegpath(RelFileLocator rlocator, ForkNumber forknum,  						 BlockNumber segno); @@ -210,7 +210,7 @@ insert_filehash_entry(const char *path)  	if (!found)  	{  		entry->path = pg_strdup(path); -		entry->isrelfile = isRelDataFile(path); +		entry->content_type = getFileContentType(path);  		entry->target_exists = false;  		entry->target_type = FILE_TYPE_UNDEFINED; @@ -294,7 +294,7 @@ process_source_file(const char *path, file_type_t type, size_t size,  	 * sanity check: a filename that looks like a data file better be a  	 * regular file  	 */ -	if (type != FILE_TYPE_REGULAR && isRelDataFile(path)) +	if (type != FILE_TYPE_REGULAR && getFileContentType(path) == FILE_CONTENT_TYPE_RELATION)  		pg_fatal("data file \"%s\" in source is not a regular file", path);  	/* Remember this source file */ @@ -383,7 +383,7 @@ process_target_wal_block_change(ForkNumber forknum, RelFileLocator rlocator,  	 */  	if (entry)  	{ -		Assert(entry->isrelfile); +		Assert(entry->content_type == FILE_CONTENT_TYPE_RELATION);  		if (entry->target_exists)  		{ @@ -560,22 +560,35 @@ print_filemap(filemap_t *filemap)  }  /* - * Does it look like a relation data file? - * - * For our purposes, only files belonging to the main fork are considered - * relation files. Other forks are always copied in toto, because we cannot - * reliably track changes to them, because WAL only contains block references - * for the main fork. + * Determine what kind of file this one looks like.   */ -static bool -isRelDataFile(const char *path) +static file_content_type_t +getFileContentType(const char *path)  {  	RelFileLocator rlocator;  	unsigned int segNo;  	int			nmatch; -	bool		matched; +	file_content_type_t result = FILE_CONTENT_TYPE_OTHER; + +	/* Check if it is a WAL file. */ +	if (strncmp("pg_wal/", path, 7) == 0) +	{ +		const char *filename = path + 7;	/* Skip "pg_wal/" */ + +		if (IsXLogFileName(filename)) +			return FILE_CONTENT_TYPE_WAL; +		else +			return FILE_CONTENT_TYPE_OTHER; +	}  	/*---- +	 * Does it look like a relation data file? +	 * +	 * For our purposes, only files belonging to the main fork are considered +	 * relation files. Other forks are always copied in toto, because we +	 * cannot reliably track changes to them, because WAL only contains block +	 * references for the main fork. +	 *  	 * Relation data files can be in one of the following directories:  	 *  	 * global/ @@ -598,14 +611,14 @@ isRelDataFile(const char *path)  	rlocator.dbOid = InvalidOid;  	rlocator.relNumber = InvalidRelFileNumber;  	segNo = 0; -	matched = false; +	result = FILE_CONTENT_TYPE_OTHER;  	nmatch = sscanf(path, "global/%u.%u", &rlocator.relNumber, &segNo);  	if (nmatch == 1 || nmatch == 2)  	{  		rlocator.spcOid = GLOBALTABLESPACE_OID;  		rlocator.dbOid = 0; -		matched = true; +		result = FILE_CONTENT_TYPE_RELATION;  	}  	else  	{ @@ -614,7 +627,7 @@ isRelDataFile(const char *path)  		if (nmatch == 2 || nmatch == 3)  		{  			rlocator.spcOid = DEFAULTTABLESPACE_OID; -			matched = true; +			result = FILE_CONTENT_TYPE_RELATION;  		}  		else  		{ @@ -622,7 +635,7 @@ isRelDataFile(const char *path)  							&rlocator.spcOid, &rlocator.dbOid, &rlocator.relNumber,  							&segNo);  			if (nmatch == 3 || nmatch == 4) -				matched = true; +				result = FILE_CONTENT_TYPE_RELATION;  		}  	} @@ -632,17 +645,17 @@ isRelDataFile(const char *path)  	 * creates the exact same filename, when passed the RelFileLocator  	 * information we extracted from the filename.  	 */ -	if (matched) +	if (result == FILE_CONTENT_TYPE_RELATION)  	{  		char	   *check_path = datasegpath(rlocator, MAIN_FORKNUM, segNo);  		if (strcmp(check_path, path) != 0) -			matched = false; +			result = FILE_CONTENT_TYPE_OTHER;  		pfree(check_path);  	} -	return matched; +	return result;  }  /* @@ -799,7 +812,12 @@ decide_file_action(file_entry_t *entry)  			return FILE_ACTION_NONE;  		case FILE_TYPE_REGULAR: -			if (!entry->isrelfile) +			if (entry->content_type == FILE_CONTENT_TYPE_WAL) +			{ +				/* It's a WAL file, copy it. */ +				return FILE_ACTION_COPY; +			} +			else if (entry->content_type != FILE_CONTENT_TYPE_RELATION)  			{  				/*  				 * It's a non-data file that we have no special processing diff --git a/src/bin/pg_rewind/filemap.h b/src/bin/pg_rewind/filemap.h index df78a02e3da..fada420fc23 100644 --- a/src/bin/pg_rewind/filemap.h +++ b/src/bin/pg_rewind/filemap.h @@ -36,6 +36,13 @@ typedef enum  	FILE_TYPE_SYMLINK,  } file_type_t; +typedef enum +{ +	FILE_CONTENT_TYPE_OTHER = 0, +	FILE_CONTENT_TYPE_RELATION, +	FILE_CONTENT_TYPE_WAL +} file_content_type_t; +  /*   * For every file found in the local or remote system, we have a file entry   * that contains information about the file on both systems.  For relation @@ -51,7 +58,7 @@ typedef struct file_entry_t  	uint32		status;			/* hash status */  	const char *path; -	bool		isrelfile;		/* is it a relation data file? */ +	file_content_type_t content_type;  	/*  	 * Status of the file in the target. diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 377a7946585..c13f92988ee 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3622,6 +3622,7 @@ fe_scram_state  fe_scram_state_enum  fetch_range_request  file_action_t +file_content_type_t  file_entry_t  file_type_t  filehash_hash | 
