Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+40-5
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)