Skip to content

Commit 6754fe6

Browse files
amcheck: Skip unlogged relations during recovery.
contrib/amcheck failed to consider the possibility that unlogged relations will not have any main relation fork files when running in hot standby mode. This led to low-level "can't happen" errors that complain about the absence of a relfilenode file. To fix, simply skip verification of unlogged index relations during recovery. In passing, add a direct check for the presence of a main fork just before verification proper begins, so that we cleanly verify the presence of the main relation fork file. Author: Andrey Borodin, Peter Geoghegan Reported-By: Andrey Borodin Diagnosed-By: Andrey Borodin Discussion: https://postgr.es/m/DA9B33AC-53CB-4643-96D4-7A0BBC037FA1@yandex-team.ru Backpatch: 10-, where amcheck was introduced.
1 parent 03c811a commit 6754fe6

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

contrib/amcheck/verify_nbtree.c

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "lib/bloomfilter.h"
3636
#include "miscadmin.h"
3737
#include "storage/lmgr.h"
38+
#include "storage/smgr.h"
3839
#include "utils/memutils.h"
3940
#include "utils/snapmgr.h"
4041

@@ -128,6 +129,7 @@ PG_FUNCTION_INFO_V1(bt_index_parent_check);
128129
static void bt_index_check_internal(Oid indrelid, bool parentcheck,
129130
bool heapallindexed, bool rootdescend);
130131
static inline void btree_index_checkable(Relation rel);
132+
static inline bool btree_index_mainfork_expected(Relation rel);
131133
static void bt_check_every_level(Relation rel, Relation heaprel,
132134
bool heapkeyspace, bool readonly, bool heapallindexed,
133135
bool rootdescend);
@@ -225,7 +227,6 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
225227
Oid heapid;
226228
Relation indrel;
227229
Relation heaprel;
228-
bool heapkeyspace;
229230
LOCKMODE lockmode;
230231

231232
if (parentcheck)
@@ -275,10 +276,22 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
275276
/* Relation suitable for checking as B-Tree? */
276277
btree_index_checkable(indrel);
277278

278-
/* Check index, possibly against table it is an index on */
279-
heapkeyspace = _bt_heapkeyspace(indrel);
280-
bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck,
281-
heapallindexed, rootdescend);
279+
if (btree_index_mainfork_expected(indrel))
280+
{
281+
bool heapkeyspace;
282+
283+
RelationOpenSmgr(indrel);
284+
if (!smgrexists(indrel->rd_smgr, MAIN_FORKNUM))
285+
ereport(ERROR,
286+
(errcode(ERRCODE_INDEX_CORRUPTED),
287+
errmsg("index \"%s\" lacks a main relation fork",
288+
RelationGetRelationName(indrel))));
289+
290+
/* Check index, possibly against table it is an index on */
291+
heapkeyspace = _bt_heapkeyspace(indrel);
292+
bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck,
293+
heapallindexed, rootdescend);
294+
}
282295

283296
/*
284297
* Release locks early. That's ok here because nothing in the called
@@ -324,6 +337,28 @@ btree_index_checkable(Relation rel)
324337
errdetail("Index is not valid.")));
325338
}
326339

340+
/*
341+
* Check if B-Tree index relation should have a file for its main relation
342+
* fork. Verification uses this to skip unlogged indexes when in hot standby
343+
* mode, where there is simply nothing to verify.
344+
*
345+
* NB: Caller should call btree_index_checkable() before calling here.
346+
*/
347+
static inline bool
348+
btree_index_mainfork_expected(Relation rel)
349+
{
350+
if (rel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED ||
351+
!RecoveryInProgress())
352+
return true;
353+
354+
ereport(NOTICE,
355+
(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
356+
errmsg("cannot verify unlogged index \"%s\" during recovery, skipping",
357+
RelationGetRelationName(rel))));
358+
359+
return false;
360+
}
361+
327362
/*
328363
* Main entry point for B-Tree SQL-callable functions. Walks the B-Tree in
329364
* logical order, verifying invariants as it goes. Optionally, verification

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy