mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	Fix BRIN 32-bit counter wrap issue with huge tables
A BlockNumber (32-bit) might not be large enough to add bo_pagesPerRange to when the table contains close to 2^32 pages. At worst, this could result in a cancellable infinite loop during the BRIN index scan with power-of-2 pagesPerRange, and slow (inefficient) BRIN index scans and scanning of unneeded heap blocks for non power-of-2 pagesPerRange. Backpatch to all supported versions. Author: sunil s <sunilfeb26@gmail.com> Reviewed-by: David Rowley <dgrowleyml@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Discussion: https://postgr.es/m/CAOG6S4-tGksTQhVzJM19NzLYAHusXsK2HmADPZzGQcfZABsvpA@mail.gmail.com Backpatch-through: 13
This commit is contained in:
		| @@ -360,7 +360,6 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) | ||||
| 	Relation	heapRel; | ||||
| 	BrinOpaque *opaque; | ||||
| 	BlockNumber nblocks; | ||||
| 	BlockNumber heapBlk; | ||||
| 	int64		totalpages = 0; | ||||
| 	FmgrInfo   *consistentFn; | ||||
| 	MemoryContext oldcxt; | ||||
| @@ -521,9 +520,10 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) | ||||
| 	/* | ||||
| 	 * Now scan the revmap.  We start by querying for heap page 0, | ||||
| 	 * incrementing by the number of pages per range; this gives us a full | ||||
| 	 * view of the table. | ||||
| 	 * view of the table.  We make use of uint64 for heapBlk as a BlockNumber | ||||
| 	 * could wrap for tables with close to 2^32 pages. | ||||
| 	 */ | ||||
| 	for (heapBlk = 0; heapBlk < nblocks; heapBlk += opaque->bo_pagesPerRange) | ||||
| 	for (uint64 heapBlk = 0; heapBlk < nblocks; heapBlk += opaque->bo_pagesPerRange) | ||||
| 	{ | ||||
| 		bool		addrange; | ||||
| 		bool		gottuple = false; | ||||
| @@ -535,7 +535,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) | ||||
|  | ||||
| 		MemoryContextResetAndDeleteChildren(perRangeCxt); | ||||
|  | ||||
| 		tup = brinGetTupleForHeapBlock(opaque->bo_rmAccess, heapBlk, &buf, | ||||
| 		tup = brinGetTupleForHeapBlock(opaque->bo_rmAccess, (BlockNumber ) heapBlk, &buf, | ||||
| 									   &off, &size, BUFFER_LOCK_SHARE, | ||||
| 									   scan->xs_snapshot); | ||||
| 		if (tup) | ||||
| @@ -711,7 +711,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm) | ||||
| 		/* add the pages in the range to the output bitmap, if needed */ | ||||
| 		if (addrange) | ||||
| 		{ | ||||
| 			BlockNumber pageno; | ||||
| 			uint64 pageno; | ||||
|  | ||||
| 			for (pageno = heapBlk; | ||||
| 				 pageno <= Min(nblocks, heapBlk + opaque->bo_pagesPerRange) - 1; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user