mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Fix amcheck child check pg_upgrade bug.
Commit d114cc53 overlooked the fact that pg_upgrade'd B-Tree indexes have leaf page high keys whose offset numbers do not match the one from the copy of the tuple one level up (the copy stored with a downlink for leaf page's right sibling page). This led to false positive reports of corruption from bt_index_parent_check() when it was called to verify a pg_upgrade'd index. To fix, skip comparing the offset number on pg_upgrade'd B-Tree indexes. Author: Anastasia Lubennikova <a.lubennikova@postgrespro.ru> Author: Peter Geoghegan <pg@bowt.ie> Reported-By: Andrew Bille <andrewbille@gmail.com> Diagnosed-By: Anastasia Lubennikova <a.lubennikova@postgrespro.ru> Bug: #16619 Discussion: https://postgr.es/m/16619-aaba10f83fdc1c3c@postgresql.org Backpatch: 13-, where child check was enhanced.
This commit is contained in:
		
							parent
							
								
									e5fac1cb19
								
							
						
					
					
						commit
						aac80bfcdd
					
				| @ -1752,14 +1752,36 @@ bt_right_page_check_scankey(BtreeCheckState *state) | ||||
|  * this function is capable to compare pivot keys on different levels. | ||||
|  */ | ||||
| static bool | ||||
| bt_pivot_tuple_identical(IndexTuple itup1, IndexTuple itup2) | ||||
| bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2) | ||||
| { | ||||
| 	if (IndexTupleSize(itup1) != IndexTupleSize(itup2)) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (heapkeyspace) | ||||
| 	{ | ||||
| 		/*
 | ||||
| 		 * Offset number will contain important information in heapkeyspace | ||||
| 		 * indexes: the number of attributes left in the pivot tuple following | ||||
| 		 * suffix truncation.  Don't skip over it (compare it too). | ||||
| 		 */ | ||||
| 		if (memcmp(&itup1->t_tid.ip_posid, &itup2->t_tid.ip_posid, | ||||
| 			   IndexTupleSize(itup1) - offsetof(ItemPointerData, ip_posid)) != 0) | ||||
| 				   IndexTupleSize(itup1) - | ||||
| 				   offsetof(ItemPointerData, ip_posid)) != 0) | ||||
| 			return false; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/*
 | ||||
| 		 * Cannot rely on offset number field having consistent value across | ||||
| 		 * levels on pg_upgrade'd !heapkeyspace indexes.  Compare contents of | ||||
| 		 * tuple starting from just after item pointer (i.e. after block | ||||
| 		 * number and offset number). | ||||
| 		 */ | ||||
| 		if (memcmp(&itup1->t_info, &itup2->t_info, | ||||
| 				   IndexTupleSize(itup1) - | ||||
| 				   offsetof(IndexTupleData, t_info)) != 0) | ||||
| 			return false; | ||||
| 	} | ||||
| 
 | ||||
| 	return true; | ||||
| } | ||||
| @ -1913,7 +1935,7 @@ bt_child_highkey_check(BtreeCheckState *state, | ||||
| 		rightsplit = P_INCOMPLETE_SPLIT(opaque); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * If we visit page with high key, check that it is be equal to the | ||||
| 		 * If we visit page with high key, check that it is equal to the | ||||
| 		 * target key next to corresponding downlink. | ||||
| 		 */ | ||||
| 		if (!rightsplit && !P_RIGHTMOST(opaque)) | ||||
| @ -2007,7 +2029,7 @@ bt_child_highkey_check(BtreeCheckState *state, | ||||
| 				itup = state->lowkey; | ||||
| 			} | ||||
| 
 | ||||
| 			if (!bt_pivot_tuple_identical(highkey, itup)) | ||||
| 			if (!bt_pivot_tuple_identical(state->heapkeyspace, highkey, itup)) | ||||
| 			{ | ||||
| 				ereport(ERROR, | ||||
| 						(errcode(ERRCODE_INDEX_CORRUPTED), | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user