summaryrefslogtreecommitdiff
path: root/src/bin/pg_rewind/filemap.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2025-10-23 15:57:46 +0900
committerMichael Paquier <michael@paquier.xyz>2025-10-23 15:57:46 +0900
commit6ae08d9583e9a5e951286948bdd9fcd58e67718a (patch)
treec0ae8f924e923da5d5cb4bb67109201006d0d957 /src/bin/pg_rewind/filemap.c
parentabc2b71383b4c49c2fbda74c281d50f3936551b8 (diff)
pg_rewind: Extend code detecting relation files to work with WAL files
isRelDataFile() is renamed to getFileContentType(), extended so as it becomes able to detect more file patterns than only relation files. The new file name pattern that can be detected is WAL files. This refactoring has been suggested by Robert Haas. This will be used in a follow-up patch where we are looking at improving how WAL files are processed by pg_rewind. As of this change, WAL files are still handled the same way as previously, always copied from the source to the target server. Extracted from a larger patch by the same authors. Author: John Hsu <johnhyvr@gmail.com> Author: Justin Kwan <justinpkwan@outlook.com> Reviewed-by: Japin Li <japinli@hotmail.com> Reviewed-by: Srinath Reddy Sadipiralla <srinath2133@gmail.com> Discussion: https://postgr.es/m/181b4c6fa9c.b8b725681941212.7547232617810891479@viggy28.dev
Diffstat (limited to 'src/bin/pg_rewind/filemap.c')
-rw-r--r--src/bin/pg_rewind/filemap.c60
1 files changed, 39 insertions, 21 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