Skip to content

Commit bf87d3c

Browse files
Fixup: Adjust SLRU download hook API
1 parent 028497f commit bf87d3c

File tree

5 files changed

+67
-101
lines changed

5 files changed

+67
-101
lines changed

src/backend/access/transam/slru.c

Lines changed: 48 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -725,64 +725,29 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruWriteAll fdata)
725725
}
726726

727727
/*
728-
* NEON: we do not want to include large pg_xact/multixact files in basebackup and prefer
729-
* to download them on demand to reduce startup time.
730-
* If SLRU segment is not found, we try to download it from page server
728+
* NEON: we do not want to include large pg_xact/multixact files in the
729+
* basebackup and prefer to download them on demand to reduce startup time.
730+
*
731+
* If SLRU segment is not found, we try to download it from the pageserver.
732+
*
733+
* Returns:
734+
* true if the file was successfully downloaded
735+
* false if the file was not found in pageserver
736+
* ereports if some other error happened
731737
*/
732-
static int
733-
SimpleLruDownloadSegment(SlruCtl ctl, int pageno, char const* path)
738+
static bool
739+
SimpleLruDownloadSegment(SlruCtl ctl, int pageno, char const *path)
734740
{
735741
SlruShared shared = ctl->shared;
736-
int segno;
737-
int fd = -1;
738-
int n_blocks;
739-
char* buffer;
742+
int segno;
740743

741744
/* If page is greater than latest written page, then do not try to download segment from server */
742745
if (ctl->PagePrecedes(pg_atomic_read_u64(&shared->latest_page_number), pageno))
743-
return -1;
746+
return false;
744747

745748
segno = pageno / SLRU_PAGES_PER_SEGMENT;
746749

747-
if (neon_use_communicator_worker) {
748-
buffer = NULL;
749-
} else {
750-
buffer = palloc(BLCKSZ * SLRU_PAGES_PER_SEGMENT);
751-
}
752-
753-
n_blocks = read_slru_segment(path, segno, buffer);
754-
if (n_blocks > 0)
755-
{
756-
fd = OpenTransientFile(path, O_RDWR | O_CREAT | PG_BINARY);
757-
if (fd < 0)
758-
{
759-
slru_errcause = SLRU_OPEN_FAILED;
760-
slru_errno = errno;
761-
pfree(buffer);
762-
return -1;
763-
}
764-
765-
if (!neon_use_communicator_worker) {
766-
errno = 0;
767-
pgstat_report_wait_start(WAIT_EVENT_SLRU_WRITE);
768-
if (pg_pwrite(fd, buffer, n_blocks*BLCKSZ, 0) != n_blocks*BLCKSZ)
769-
{
770-
pgstat_report_wait_end();
771-
/* if write didn't set errno, assume problem is no disk space */
772-
if (errno == 0)
773-
errno = ENOSPC;
774-
slru_errcause = SLRU_WRITE_FAILED;
775-
slru_errno = errno;
776-
777-
CloseTransientFile(fd);
778-
pfree(buffer);
779-
return -1;
780-
}
781-
pgstat_report_wait_end();
782-
}
783-
}
784-
pfree(buffer);
785-
return fd;
750+
return smgr_read_slru_segment(path, segno);
786751
}
787752

788753
/*
@@ -813,29 +778,34 @@ SimpleLruDoesPhysicalPageExist(SlruCtl ctl, int64 pageno)
813778
int fd;
814779
bool result;
815780
off_t endpos;
781+
bool attempted_download = false;
816782

817783
/* update the stats counter of checked pages */
818784
pgstat_count_slru_page_exists(ctl->shared->slru_stats_idx);
819785

820786
SlruFileName(ctl, path, segno);
821787

788+
retry_after_download:
822789
fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
823790
if (fd < 0)
824791
{
825-
/* expected: file doesn't exist */
826-
if (errno == ENOENT)
792+
if (errno == ENOENT && !attempted_download)
827793
{
828-
fd = SimpleLruDownloadSegment(ctl, pageno, path);
829-
if (fd < 0)
830-
return false;
831-
}
832-
else
833-
{
834-
/* report error normally */
835-
slru_errcause = SLRU_OPEN_FAILED;
836-
slru_errno = errno;
837-
SlruReportIOError(ctl, pageno, 0);
794+
/* Try to download the file from the pageserver */
795+
attempted_download = true;
796+
if (SimpleLruDownloadSegment(ctl, pageno, path))
797+
goto retry_after_download;
798+
errno = ENOENT;
838799
}
800+
801+
/* expected: file doesn't exist */
802+
if (errno == ENOENT)
803+
return false;
804+
805+
/* report error normally */
806+
slru_errcause = SLRU_OPEN_FAILED;
807+
slru_errno = errno;
808+
SlruReportIOError(ctl, pageno, 0);
839809
}
840810

841811
if ((endpos = lseek(fd, 0, SEEK_END)) < 0)
@@ -876,6 +846,7 @@ SlruPhysicalReadPage(SlruCtl ctl, int64 pageno, int slotno)
876846
off_t offset = rpageno * BLCKSZ;
877847
char path[MAXPGPATH];
878848
int fd;
849+
bool attempted_download = false;
879850

880851
SlruFileName(ctl, path, segno);
881852

@@ -886,34 +857,31 @@ SlruPhysicalReadPage(SlruCtl ctl, int64 pageno, int slotno)
886857
* SlruPhysicalWritePage). Hence, if we are InRecovery, allow the case
887858
* where the file doesn't exist, and return zeroes instead.
888859
*/
860+
retry_after_download:
889861
fd = OpenTransientFile(path, O_RDONLY | PG_BINARY);
890862
if (fd < 0)
891863
{
892-
if (errno != ENOENT)
864+
if (errno == ENOENT && !attempted_download)
865+
{
866+
/* Try to download the file from the pageserver */
867+
attempted_download = true;
868+
if (SimpleLruDownloadSegment(ctl, pageno, path))
869+
goto retry_after_download;
870+
errno = ENOENT;
871+
}
872+
873+
if (errno != ENOENT || !InRecovery)
893874
{
894875
slru_errcause = SLRU_OPEN_FAILED;
895876
slru_errno = errno;
896877
return false;
897878
}
898879

899-
fd = SimpleLruDownloadSegment(ctl, pageno, path);
900-
if (fd < 0)
901-
{
902-
if (!InRecovery)
903-
{
904-
slru_errcause = SLRU_OPEN_FAILED;
905-
slru_errno = errno;
906-
return false;
907-
}
908-
else
909-
{
910-
ereport(LOG,
911-
(errmsg("file \"%s\" doesn't exist, reading as zeroes",
912-
path)));
913-
MemSet(shared->page_buffer[slotno], 0, BLCKSZ);
914-
return true;
915-
}
916-
}
880+
ereport(LOG,
881+
(errmsg("file \"%s\" doesn't exist, reading as zeroes",
882+
path)));
883+
MemSet(shared->page_buffer[slotno], 0, BLCKSZ);
884+
return true;
917885
}
918886

919887
errno = 0;

src/backend/storage/smgr/smgr.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ static int NSmgr = 1;
106106
start_unlogged_build_hook_type start_unlogged_build_hook;
107107
finish_unlogged_build_phase_1_hook_type finish_unlogged_build_phase_1_hook;
108108
end_unlogged_build_hook_type end_unlogged_build_hook;
109+
110+
/*
111+
* SLRU download isn't really part of the smgr API, as SLRUs are not
112+
* relations. But we define this here anyway, to keep it close to the smgr
113+
* hooks in Neon.
114+
*/
109115
read_slru_segment_hook_type read_slru_segment_hook;
110116

111117
/*
@@ -1089,23 +1095,22 @@ smgr_end_unlogged_build(SMgrRelation reln)
10891095
}
10901096

10911097
/*
1092-
* NEON: we do not want to include large pg_xact/multixact files in basebackup and prefer
1093-
* to download them on demand to reduce startup time.
1094-
* If SLRU segment is not found, we try to download it from page server
1098+
* NEON: Attempt to download an SLRU file from remote storage.
10951099
*
1096-
* This function returns number of blocks in segment. Usually it should be SLRU_PAGES_PER_SEGMENT but in case
1097-
* of partial segment, it can be smaller. Zero value means that segment doesn't exist.
1098-
* From Postgres point of view empty segment is the same as absent segment.
1100+
* To reduce startup time, we don't want to include large pg_xact/multixact
1101+
* files in the basebackup. Instead, we have this hook to download them on
1102+
* demand. If an SLRU segment is not found, the code in slru.c calls this to
1103+
* check if it can be downloaded from the pageserver.
10991104
*
1100-
* This should really be a separate hook, not something that's in the smgr API, but
1101-
* oh well.
1105+
* If the segment is found in remote storage, the hook writes it to the local
1106+
* file and returns 'true'. If the file is not found, returns 'false'.
11021107
*/
1103-
int
1104-
read_slru_segment(const char* path, int segno, void* buffer)
1108+
bool
1109+
smgr_read_slru_segment(const char *path, int segno)
11051110
{
11061111
if (read_slru_segment_hook)
1107-
return read_slru_segment_hook(path, segno, buffer);
1108-
return 0;
1112+
return read_slru_segment_hook(path, segno);
1113+
return false;
11091114
}
11101115

11111116
/*

src/backend/utils/init/globals.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ pid_t PostmasterPid = 0;
119119
bool IsPostmasterEnvironment = false;
120120
bool IsUnderPostmaster = false;
121121
bool IsBinaryUpgrade = false;
122-
bool neon_use_communicator_worker = false;
123122

124123
bool ExitOnAnyError = false;
125124

src/include/miscadmin.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,12 +170,6 @@ extern PGDLLIMPORT pid_t PostmasterPid;
170170
extern PGDLLIMPORT bool IsPostmasterEnvironment;
171171
extern PGDLLIMPORT bool IsUnderPostmaster;
172172
extern PGDLLIMPORT bool IsBinaryUpgrade;
173-
/* Whether the communicator worker is used or not. Defined here so that
174-
* it is also accessible from the main postgres code easily without
175-
* having to look up the value using strings and chain of other
176-
* functions.
177-
*/
178-
extern PGDLLIMPORT bool neon_use_communicator_worker;
179173

180174
extern PGDLLIMPORT bool ExitOnAnyError;
181175

src/include/storage/smgr.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ extern finish_unlogged_build_phase_1_hook_type finish_unlogged_build_phase_1_hoo
155155
extern end_unlogged_build_hook_type end_unlogged_build_hook;
156156

157157
/* NEON: Hook for reading an SLRU segment from e.g. remote storage */
158-
typedef int (*read_slru_segment_hook_type) (const char *path, int segno, void* buffer);
158+
typedef bool (*read_slru_segment_hook_type) (const char *path, int segno);
159159
extern read_slru_segment_hook_type read_slru_segment_hook;
160160

161161
/* NEON: Alternative implementation of calculate_database_size(), to make it O(1) */
@@ -217,7 +217,7 @@ extern void smgr_finish_unlogged_build_phase_1(SMgrRelation reln);
217217
extern void smgr_end_unlogged_build(SMgrRelation reln);
218218

219219
/* Neon: Allow on-demand download of SLRU segment data */
220-
extern int read_slru_segment(const char *path, int segno, void* buffer);
220+
extern bool smgr_read_slru_segment(const char *path, int segno);
221221

222222
static inline void
223223
smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,

0 commit comments

Comments
 (0)