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 | static void | ||||||
| check_tuple(HeapCheckContext *ctx) | 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 | 	 * Check various forms of tuple header corruption, and if the header is too | ||||||
| 	 * within the page cannot be trusted, leaving too much risk of reading | 	 * corrupt, do not continue with other checks. | ||||||
| 	 * 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. |  | ||||||
| 	 */ | 	 */ | ||||||
| 	if (!check_tuple_header(ctx)) | 	if (!check_tuple_header(ctx)) | ||||||
| 		return; | 		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)) | 	if (!check_tuple_visibility(ctx)) | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user