mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									03c811a483
								
							
						
					
					
						commit
						6754fe65a4
					
				| @ -35,6 +35,7 @@ | ||||
| #include "lib/bloomfilter.h" | ||||
| #include "miscadmin.h" | ||||
| #include "storage/lmgr.h" | ||||
| #include "storage/smgr.h" | ||||
| #include "utils/memutils.h" | ||||
| #include "utils/snapmgr.h" | ||||
| 
 | ||||
| @ -128,6 +129,7 @@ PG_FUNCTION_INFO_V1(bt_index_parent_check); | ||||
| static void bt_index_check_internal(Oid indrelid, bool parentcheck, | ||||
| 									bool heapallindexed, bool rootdescend); | ||||
| static inline void btree_index_checkable(Relation rel); | ||||
| static inline bool btree_index_mainfork_expected(Relation rel); | ||||
| static void bt_check_every_level(Relation rel, Relation heaprel, | ||||
| 								 bool heapkeyspace, bool readonly, bool heapallindexed, | ||||
| 								 bool rootdescend); | ||||
| @ -225,7 +227,6 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, | ||||
| 	Oid			heapid; | ||||
| 	Relation	indrel; | ||||
| 	Relation	heaprel; | ||||
| 	bool		heapkeyspace; | ||||
| 	LOCKMODE	lockmode; | ||||
| 
 | ||||
| 	if (parentcheck) | ||||
| @ -275,10 +276,22 @@ bt_index_check_internal(Oid indrelid, bool parentcheck, bool heapallindexed, | ||||
| 	/* Relation suitable for checking as B-Tree? */ | ||||
| 	btree_index_checkable(indrel); | ||||
| 
 | ||||
| 	/* Check index, possibly against table it is an index on */ | ||||
| 	heapkeyspace = _bt_heapkeyspace(indrel); | ||||
| 	bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck, | ||||
| 						 heapallindexed, rootdescend); | ||||
| 	if (btree_index_mainfork_expected(indrel)) | ||||
| 	{ | ||||
| 		bool	heapkeyspace; | ||||
| 
 | ||||
| 		RelationOpenSmgr(indrel); | ||||
| 		if (!smgrexists(indrel->rd_smgr, MAIN_FORKNUM)) | ||||
| 			ereport(ERROR, | ||||
| 					(errcode(ERRCODE_INDEX_CORRUPTED), | ||||
| 					 errmsg("index \"%s\" lacks a main relation fork", | ||||
| 							RelationGetRelationName(indrel)))); | ||||
| 
 | ||||
| 		/* Check index, possibly against table it is an index on */ | ||||
| 		heapkeyspace = _bt_heapkeyspace(indrel); | ||||
| 		bt_check_every_level(indrel, heaprel, heapkeyspace, parentcheck, | ||||
| 							 heapallindexed, rootdescend); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Release locks early. That's ok here because nothing in the called | ||||
| @ -324,6 +337,28 @@ btree_index_checkable(Relation rel) | ||||
| 				 errdetail("Index is not valid."))); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Check if B-Tree index relation should have a file for its main relation | ||||
|  * fork.  Verification uses this to skip unlogged indexes when in hot standby | ||||
|  * mode, where there is simply nothing to verify. | ||||
|  * | ||||
|  * NB: Caller should call btree_index_checkable() before calling here. | ||||
|  */ | ||||
| static inline bool | ||||
| btree_index_mainfork_expected(Relation rel) | ||||
| { | ||||
| 	if (rel->rd_rel->relpersistence != RELPERSISTENCE_UNLOGGED || | ||||
| 		!RecoveryInProgress()) | ||||
| 		return true; | ||||
| 
 | ||||
| 	ereport(NOTICE, | ||||
| 			(errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION), | ||||
| 			 errmsg("cannot verify unlogged index \"%s\" during recovery, skipping", | ||||
| 					RelationGetRelationName(rel)))); | ||||
| 
 | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Main entry point for B-Tree SQL-callable functions. Walks the B-Tree in | ||||
|  * logical order, verifying invariants as it goes.  Optionally, verification | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user