Hi,
load_relcache_init_file() treats a zero-length fread() of the next
relation descriptor length as the end of pg_internal.init, which has
no record count. fread() also returns zero when a read error
transfers no data. In that case the file is accepted whenever the
nailed rel and index counts already match, so a partial cache can be
installed instead of bootstrapping it from the built-in descriptors.
Check ferror() before treating a zero-length read as the end of the
file.
The patch is attached.
Regards,
Evgeniy Gorbanyov
From 6b6bf90f1190dd49eafdfd1475a7c597fcfd108c Mon Sep 17 00:00:00 2001
From: Evgeniy Gorbanyov <[email protected]>
Date: Wed, 11 Nov 2026 14:23:50 +0600
Subject: [PATCH] Distinguish EOF from a read error when loading the relcache
init file
load_relcache_init_file() treats a zero-length fread() of the next
relation descriptor length as the end of pg_internal.init, which has
no record count. fread() also returns zero when a read error
transfers no data. In that case the file is accepted whenever the
nailed rel and index counts already match, so a partial cache can be
installed instead of bootstrapping it from the built-in descriptors.
Check ferror() before treating a zero-length read as the end of the
file.
Signed-off-by: Evgeniy Gorbanyov <[email protected]>
---
src/backend/utils/cache/relcache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 07868bafee2..cdd33306ed7 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -6329,7 +6329,7 @@ load_relcache_init_file(bool shared)
nread = fread(&len, 1, sizeof(len), fp);
if (nread != sizeof(len))
{
- if (nread == 0)
+ if (nread == 0 && !ferror(fp))
break; /* end of file */
goto read_failed;
}
--
2.50.1