mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	amcheck: Remove duplicate XID/MXID bounds checks.
Commit 3b6c1259f9ca8e21860aaf24ec6735a8e5598ea0 resulted in the same xmin and xmax bounds checking being performed in both check_tuple() and check_tuple_visibility(). Remove the duplication. While at it, adjust some code comments that were overlooked in that commit. Mark Dilger Discussion: http://postgr.es/m/AC5479E4-6321-473D-AC92-5EC36299FBC2@enterprisedb.com
This commit is contained in:
		
							parent
							
								
									3c3b8a4b26
								
							
						
					
					
						commit
						4573f6a9af
					
				| @ -1390,136 +1390,18 @@ check_tuple_attribute(HeapCheckContext *ctx) | ||||
| static void | ||||
| check_tuple(HeapCheckContext *ctx) | ||||
| { | ||||
| 	TransactionId xmin; | ||||
| 	TransactionId xmax; | ||||
| 	bool		fatal = false; | ||||
| 	uint16		infomask = ctx->tuphdr->t_infomask; | ||||
| 
 | ||||
| 	/* If xmin is normal, it should be within valid range */ | ||||
| 	xmin = HeapTupleHeaderGetXmin(ctx->tuphdr); | ||||
| 	switch (get_xid_status(xmin, ctx, NULL)) | ||||
| 	{ | ||||
| 		case XID_INVALID: | ||||
| 		case XID_BOUNDS_OK: | ||||
| 			break; | ||||
| 		case XID_IN_FUTURE: | ||||
| 			report_corruption(ctx, | ||||
| 							  psprintf("xmin %u equals or exceeds next valid transaction ID %u:%u", | ||||
| 									   xmin, | ||||
| 									   EpochFromFullTransactionId(ctx->next_fxid), | ||||
| 									   XidFromFullTransactionId(ctx->next_fxid))); | ||||
| 			fatal = true; | ||||
| 			break; | ||||
| 		case XID_PRECEDES_CLUSTERMIN: | ||||
| 			report_corruption(ctx, | ||||
| 							  psprintf("xmin %u precedes oldest valid transaction ID %u:%u", | ||||
| 									   xmin, | ||||
| 									   EpochFromFullTransactionId(ctx->oldest_fxid), | ||||
| 									   XidFromFullTransactionId(ctx->oldest_fxid))); | ||||
| 			fatal = true; | ||||
| 			break; | ||||
| 		case XID_PRECEDES_RELMIN: | ||||
| 			report_corruption(ctx, | ||||
| 							  psprintf("xmin %u precedes relation freeze threshold %u:%u", | ||||
| 									   xmin, | ||||
| 									   EpochFromFullTransactionId(ctx->relfrozenfxid), | ||||
| 									   XidFromFullTransactionId(ctx->relfrozenfxid))); | ||||
| 			fatal = true; | ||||
| 			break; | ||||
| 	} | ||||
| 
 | ||||
| 	xmax = HeapTupleHeaderGetRawXmax(ctx->tuphdr); | ||||
| 
 | ||||
| 	if (infomask & HEAP_XMAX_IS_MULTI) | ||||
| 	{ | ||||
| 		/* xmax is a multixact, so it should be within valid MXID range */ | ||||
| 		switch (check_mxid_valid_in_rel(xmax, ctx)) | ||||
| 		{ | ||||
| 			case XID_INVALID: | ||||
| 				report_corruption(ctx, | ||||
| 								  pstrdup("multitransaction ID is invalid")); | ||||
| 				fatal = true; | ||||
| 				break; | ||||
| 			case XID_PRECEDES_RELMIN: | ||||
| 				report_corruption(ctx, | ||||
| 								  psprintf("multitransaction ID %u precedes relation minimum multitransaction ID threshold %u", | ||||
| 										   xmax, ctx->relminmxid)); | ||||
| 				fatal = true; | ||||
| 				break; | ||||
| 			case XID_PRECEDES_CLUSTERMIN: | ||||
| 				report_corruption(ctx, | ||||
| 								  psprintf("multitransaction ID %u precedes oldest valid multitransaction ID threshold %u", | ||||
| 										   xmax, ctx->oldest_mxact)); | ||||
| 				fatal = true; | ||||
| 				break; | ||||
| 			case XID_IN_FUTURE: | ||||
| 				report_corruption(ctx, | ||||
| 								  psprintf("multitransaction ID %u equals or exceeds next valid multitransaction ID %u", | ||||
| 										   xmax, | ||||
| 										   ctx->next_mxact)); | ||||
| 				fatal = true; | ||||
| 				break; | ||||
| 			case XID_BOUNDS_OK: | ||||
| 				break; | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		/*
 | ||||
| 		 * xmax is not a multixact and is normal, so it should be within the | ||||
| 		 * valid XID range. | ||||
| 		 */ | ||||
| 		switch (get_xid_status(xmax, ctx, NULL)) | ||||
| 		{ | ||||
| 			case XID_INVALID: | ||||
| 			case XID_BOUNDS_OK: | ||||
| 				break; | ||||
| 			case XID_IN_FUTURE: | ||||
| 				report_corruption(ctx, | ||||
| 								  psprintf("xmax %u equals or exceeds next valid transaction ID %u:%u", | ||||
| 										   xmax, | ||||
| 										   EpochFromFullTransactionId(ctx->next_fxid), | ||||
| 										   XidFromFullTransactionId(ctx->next_fxid))); | ||||
| 				fatal = true; | ||||
| 				break; | ||||
| 			case XID_PRECEDES_CLUSTERMIN: | ||||
| 				report_corruption(ctx, | ||||
| 								  psprintf("xmax %u precedes oldest valid transaction ID %u:%u", | ||||
| 										   xmax, | ||||
| 										   EpochFromFullTransactionId(ctx->oldest_fxid), | ||||
| 										   XidFromFullTransactionId(ctx->oldest_fxid))); | ||||
| 				fatal = true; | ||||
| 				break; | ||||
| 			case XID_PRECEDES_RELMIN: | ||||
| 				report_corruption(ctx, | ||||
| 								  psprintf("xmax %u precedes relation freeze threshold %u:%u", | ||||
| 										   xmax, | ||||
| 										   EpochFromFullTransactionId(ctx->relfrozenfxid), | ||||
| 										   XidFromFullTransactionId(ctx->relfrozenfxid))); | ||||
| 				fatal = true; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Cannot process tuple data if tuple header was corrupt, as the offsets | ||||
| 	 * within the page cannot be trusted, leaving too much risk of reading | ||||
| 	 * garbage if we continue. | ||||
| 	 * | ||||
| 	 * We also cannot process the tuple if the xmin or xmax were invalid | ||||
| 	 * relative to relfrozenxid or relminmxid, as clog entries for the xids | ||||
| 	 * may already be gone. | ||||
| 	 */ | ||||
| 	if (fatal) | ||||
| 		return; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Check various forms of tuple header corruption.  If the header is too | ||||
| 	 * corrupt to continue checking, or if the tuple is not visible to anyone, | ||||
| 	 * we cannot continue with other checks. | ||||
| 	 * Check various forms of tuple header corruption, and if the header is too | ||||
| 	 * corrupt, do not continue with other checks. | ||||
| 	 */ | ||||
| 	if (!check_tuple_header(ctx)) | ||||
| 		return; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Check tuple visibility.  If the inserting transaction aborted, we | ||||
| 	 * cannot assume our relation description matches the tuple structure, and | ||||
| 	 * therefore cannot check it. | ||||
| 	 */ | ||||
| 	if (!check_tuple_visibility(ctx)) | ||||
| 		return; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user