Skip to content

Commit 6ae08d9

Browse files
committed
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 <[email protected]> Author: Justin Kwan <[email protected]> Reviewed-by: Japin Li <[email protected]> Reviewed-by: Srinath Reddy Sadipiralla <[email protected]> Discussion: https://postgr.es/m/[email protected]
1 parent abc2b71 commit 6ae08d9

File tree

3 files changed

+48
-22
lines changed

3 files changed

+48
-22
lines changed

src/bin/pg_rewind/filemap.c

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555

5656
static filehash_hash *filehash;
5757

58-
static bool isRelDataFile(const char *path);
58+
static file_content_type_t getFileContentType(const char *path);
5959
static char *datasegpath(RelFileLocator rlocator, ForkNumber forknum,
6060
BlockNumber segno);
6161

@@ -210,7 +210,7 @@ insert_filehash_entry(const char *path)
210210
if (!found)
211211
{
212212
entry->path = pg_strdup(path);
213-
entry->isrelfile = isRelDataFile(path);
213+
entry->content_type = getFileContentType(path);
214214

215215
entry->target_exists = false;
216216
entry->target_type = FILE_TYPE_UNDEFINED;
@@ -294,7 +294,7 @@ process_source_file(const char *path, file_type_t type, size_t size,
294294
* sanity check: a filename that looks like a data file better be a
295295
* regular file
296296
*/
297-
if (type != FILE_TYPE_REGULAR && isRelDataFile(path))
297+
if (type != FILE_TYPE_REGULAR && getFileContentType(path) == FILE_CONTENT_TYPE_RELATION)
298298
pg_fatal("data file \"%s\" in source is not a regular file", path);
299299

300300
/* Remember this source file */
@@ -383,7 +383,7 @@ process_target_wal_block_change(ForkNumber forknum, RelFileLocator rlocator,
383383
*/
384384
if (entry)
385385
{
386-
Assert(entry->isrelfile);
386+
Assert(entry->content_type == FILE_CONTENT_TYPE_RELATION);
387387

388388
if (entry->target_exists)
389389
{
@@ -560,22 +560,35 @@ print_filemap(filemap_t *filemap)
560560
}
561561

562562
/*
563-
* Does it look like a relation data file?
564-
*
565-
* For our purposes, only files belonging to the main fork are considered
566-
* relation files. Other forks are always copied in toto, because we cannot
567-
* reliably track changes to them, because WAL only contains block references
568-
* for the main fork.
563+
* Determine what kind of file this one looks like.
569564
*/
570-
static bool
571-
isRelDataFile(const char *path)
565+
static file_content_type_t
566+
getFileContentType(const char *path)
572567
{
573568
RelFileLocator rlocator;
574569
unsigned int segNo;
575570
int nmatch;
576-
bool matched;
571+
file_content_type_t result = FILE_CONTENT_TYPE_OTHER;
572+
573+
/* Check if it is a WAL file. */
574+
if (strncmp("pg_wal/", path, 7) == 0)
575+
{
576+
const char *filename = path + 7; /* Skip "pg_wal/" */
577+
578+
if (IsXLogFileName(filename))
579+
return FILE_CONTENT_TYPE_WAL;
580+
else
581+
return FILE_CONTENT_TYPE_OTHER;
582+
}
577583

578584
/*----
585+
* Does it look like a relation data file?
586+
*
587+
* For our purposes, only files belonging to the main fork are considered
588+
* relation files. Other forks are always copied in toto, because we
589+
* cannot reliably track changes to them, because WAL only contains block
590+
* references for the main fork.
591+
*
579592
* Relation data files can be in one of the following directories:
580593
*
581594
* global/
@@ -598,14 +611,14 @@ isRelDataFile(const char *path)
598611
rlocator.dbOid = InvalidOid;
599612
rlocator.relNumber = InvalidRelFileNumber;
600613
segNo = 0;
601-
matched = false;
614+
result = FILE_CONTENT_TYPE_OTHER;
602615

603616
nmatch = sscanf(path, "global/%u.%u", &rlocator.relNumber, &segNo);
604617
if (nmatch == 1 || nmatch == 2)
605618
{
606619
rlocator.spcOid = GLOBALTABLESPACE_OID;
607620
rlocator.dbOid = 0;
608-
matched = true;
621+
result = FILE_CONTENT_TYPE_RELATION;
609622
}
610623
else
611624
{
@@ -614,15 +627,15 @@ isRelDataFile(const char *path)
614627
if (nmatch == 2 || nmatch == 3)
615628
{
616629
rlocator.spcOid = DEFAULTTABLESPACE_OID;
617-
matched = true;
630+
result = FILE_CONTENT_TYPE_RELATION;
618631
}
619632
else
620633
{
621634
nmatch = sscanf(path, "pg_tblspc/%u/" TABLESPACE_VERSION_DIRECTORY "/%u/%u.%u",
622635
&rlocator.spcOid, &rlocator.dbOid, &rlocator.relNumber,
623636
&segNo);
624637
if (nmatch == 3 || nmatch == 4)
625-
matched = true;
638+
result = FILE_CONTENT_TYPE_RELATION;
626639
}
627640
}
628641

@@ -632,17 +645,17 @@ isRelDataFile(const char *path)
632645
* creates the exact same filename, when passed the RelFileLocator
633646
* information we extracted from the filename.
634647
*/
635-
if (matched)
648+
if (result == FILE_CONTENT_TYPE_RELATION)
636649
{
637650
char *check_path = datasegpath(rlocator, MAIN_FORKNUM, segNo);
638651

639652
if (strcmp(check_path, path) != 0)
640-
matched = false;
653+
result = FILE_CONTENT_TYPE_OTHER;
641654

642655
pfree(check_path);
643656
}
644657

645-
return matched;
658+
return result;
646659
}
647660

648661
/*
@@ -799,7 +812,12 @@ decide_file_action(file_entry_t *entry)
799812
return FILE_ACTION_NONE;
800813

801814
case FILE_TYPE_REGULAR:
802-
if (!entry->isrelfile)
815+
if (entry->content_type == FILE_CONTENT_TYPE_WAL)
816+
{
817+
/* It's a WAL file, copy it. */
818+
return FILE_ACTION_COPY;
819+
}
820+
else if (entry->content_type != FILE_CONTENT_TYPE_RELATION)
803821
{
804822
/*
805823
* It's a non-data file that we have no special processing

src/bin/pg_rewind/filemap.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ typedef enum
3636
FILE_TYPE_SYMLINK,
3737
} file_type_t;
3838

39+
typedef enum
40+
{
41+
FILE_CONTENT_TYPE_OTHER = 0,
42+
FILE_CONTENT_TYPE_RELATION,
43+
FILE_CONTENT_TYPE_WAL
44+
} file_content_type_t;
45+
3946
/*
4047
* For every file found in the local or remote system, we have a file entry
4148
* that contains information about the file on both systems. For relation
@@ -51,7 +58,7 @@ typedef struct file_entry_t
5158
uint32 status; /* hash status */
5259

5360
const char *path;
54-
bool isrelfile; /* is it a relation data file? */
61+
file_content_type_t content_type;
5562

5663
/*
5764
* Status of the file in the target.

src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3622,6 +3622,7 @@ fe_scram_state
36223622
fe_scram_state_enum
36233623
fetch_range_request
36243624
file_action_t
3625+
file_content_type_t
36253626
file_entry_t
36263627
file_type_t
36273628
filehash_hash

0 commit comments

Comments
 (0)