|
35 | 35 | #include "lib/bloomfilter.h"
|
36 | 36 | #include "miscadmin.h"
|
37 | 37 | #include "storage/lmgr.h"
|
| 38 | +#include "storage/smgr.h" |
38 | 39 | #include "utils/memutils.h"
|
39 | 40 | #include "utils/snapmgr.h"
|
40 | 41 |
|
@@ -128,6 +129,7 @@ PG_FUNCTION_INFO_V1(bt_index_parent_check);
|
128 | 129 | static void bt_index_check_internal(Oid indrelid, bool parentcheck,
|
129 | 130 | bool heapallindexed, bool rootdescend);
|
130 | 131 | static inline void btree_index_checkable(Relation rel);
|
| 132 | +static inline bool btree_index_mainfork_expected(Relation rel); |
131 | 133 | static void bt_check_every_level(Relation rel, Relation heaprel,
|
132 | 134 | bool heapkeyspace, bool readonly, bool heapallindexed,
|
133 | 135 | bool rootdescend);
|
@@ -225,7 +227,6 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
|
225 | 227 | Oid heapid;
|
226 | 228 | Relation indrel;
|
227 | 229 | Relation heaprel;
|
228 |
| - bool heapkeyspace; |
229 | 230 | LOCKMODE lockmode;
|
230 | 231 |
|
231 | 232 | if (parentcheck)
|
@@ -275,10 +276,22 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed,
|
275 | 276 | /* Relation suitable for checking as B-Tree? */
|
276 | 277 | btree_index_checkable(indrel);
|
277 | 278 |
|
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 | + } |
282 | 295 |
|
283 | 296 | /*
|
284 | 297 | * Release locks early. That's ok here because nothing in the called
|
@@ -324,6 +337,28 @@ btree_index_checkable(Relation rel)
|
324 | 337 | errdetail("Index is not valid.")));
|
325 | 338 | }
|
326 | 339 |
|
| 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 | + |
327 | 362 | /*
|
328 | 363 | * Main entry point for B-Tree SQL-callable functions. Walks the B-Tree in
|
329 | 364 | * logical order, verifying invariants as it goes. Optionally, verification
|
|
0 commit comments