|
25 | 25 | #include "commands/tablecmds.h"
|
26 | 26 | #include "miscadmin.h"
|
27 | 27 | #include "storage/lmgr.h"
|
| 28 | +#include "storage/smgr.h" |
28 | 29 | #include "utils/memutils.h"
|
29 | 30 | #include "utils/snapmgr.h"
|
30 | 31 |
|
@@ -94,6 +95,7 @@ PG_FUNCTION_INFO_V1(bt_index_parent_check);
|
94 | 95 |
|
95 | 96 | static void bt_index_check_internal(Oid indrelid, bool parentcheck);
|
96 | 97 | static inline void btree_index_checkable(Relation rel);
|
| 98 | +static inline bool btree_index_mainfork_expected(Relation rel); |
97 | 99 | static void bt_check_every_level(Relation rel, bool readonly);
|
98 | 100 | static BtreeLevel bt_check_level_from_leftmost(BtreeCheckState *state,
|
99 | 101 | BtreeLevel level);
|
@@ -204,8 +206,18 @@ bt_index_check_internal(Oid indrelid, bool parentcheck)
|
204 | 206 | /* Relation suitable for checking as B-Tree? */
|
205 | 207 | btree_index_checkable(indrel);
|
206 | 208 |
|
207 |
| - /* Check index */ |
208 |
| - bt_check_every_level(indrel, parentcheck); |
| 209 | + if (btree_index_mainfork_expected(indrel)) |
| 210 | + { |
| 211 | + RelationOpenSmgr(indrel); |
| 212 | + if (!smgrexists(indrel->rd_smgr, MAIN_FORKNUM)) |
| 213 | + ereport(ERROR, |
| 214 | + (errcode(ERRCODE_INDEX_CORRUPTED), |
| 215 | + errmsg("index \"%s\" lacks a main relation fork", |
| 216 | + RelationGetRelationName(indrel)))); |
| 217 | + |
| 218 | + /* Check index */ |
| 219 | + bt_check_every_level(indrel, parentcheck); |
| 220 | + } |
209 | 221 |
|
210 | 222 | /*
|
211 | 223 | * Release locks early. That's ok here because nothing in the called
|
@@ -251,6 +263,28 @@ btree_index_checkable(Relation rel)
|
251 | 263 | errdetail("Index is not valid")));
|
252 | 264 | }
|
253 | 265 |
|
| 266 | +/* |
| 267 | + * Check if B-Tree index relation should have a file for its main relation |
| 268 | + * fork. Verification uses this to skip unlogged indexes when in hot standby |
| 269 | + * mode, where there is simply nothing to verify. |
| 270 | + * |
| 271 | + * NB: Caller should call btree_index_checkable() before calling here. |
| 272 | + */ |
| 273 | +static inline bool |
| 274 | +btree_index_mainfork_expected(Relation rel) |
| 275 | +{ |
| 276 | + if (rel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED || |
| 277 | + !RecoveryInProgress()) |
| 278 | + return true; |
| 279 | + |
| 280 | + ereport(NOTICE, |
| 281 | + (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), |
| 282 | + errmsg("cannot verify unlogged index \"%s\" during recovery, skipping", |
| 283 | + RelationGetRelationName(rel)))); |
| 284 | + |
| 285 | + return false; |
| 286 | +} |
| 287 | + |
254 | 288 | /*
|
255 | 289 | * Main entry point for B-Tree SQL-callable functions. Walks the B-Tree in
|
256 | 290 | * logical order, verifying invariants as it goes.
|
|
0 commit comments