1515#include  <sys/stat.h> 
1616#include  <unistd.h> 
1717
18+ #include  "access/heapam.h" 
1819#include  "access/relation.h" 
1920#include  "fmgr.h" 
2021#include  "miscadmin.h" 
@@ -35,7 +36,8 @@ typedef enum
3536{
3637	PREWARM_PREFETCH ,
3738	PREWARM_READ ,
38- 	PREWARM_BUFFER 
39+ 	PREWARM_BUFFER ,
40+ 	PREWARM_TUPLE ,
3941} PrewarmType ;
4042
4143static  PGIOAlignedBlock  blockbuffer ;
@@ -88,6 +90,8 @@ pg_prewarm(PG_FUNCTION_ARGS)
8890		ptype  =  PREWARM_READ ;
8991	else  if  (strcmp (ttype , "buffer" ) ==  0 )
9092		ptype  =  PREWARM_BUFFER ;
93+ 	else  if  (strcmp (ttype , "tuple" ) ==  0 )
94+ 		ptype  =  PREWARM_TUPLE ;
9195	else 
9296	{
9397		ereport (ERROR ,
@@ -210,6 +214,33 @@ pg_prewarm(PG_FUNCTION_ARGS)
210214			++ blocks_done ;
211215		}
212216	}
217+ 	else  if  (ptype  ==  PREWARM_TUPLE )
218+ 	{
219+ 		if  (get_relkind_objtype (rel -> rd_rel -> relkind ) ==  OBJECT_TABLE  &&  forkNumber  ==  MAIN_FORKNUM )
220+ 		{
221+ 			uint32  		scan_flags  =  SO_TYPE_SEQSCAN  | SO_TEMP_SNAPSHOT ;
222+ 			HeapTuple  	tuple ;
223+ 			Snapshot  snapshot ;
224+ 			TableScanDesc  scan ;
225+ 
226+ 			elog (LOG , "pg_prewarm: SeqScan relation \"%s\" starting %ld for %ld blocks" , RelationGetRelationName (rel ), first_block , last_block  -  first_block  +  1 );
227+ 			// Use heap scan to set hint bits on every tuple. SO_ALLOW_PAGEMODE is intentionally NOT SET. 
228+ 			// Otherwise, when a page is all visible, tuple hint bits won't be set. 
229+ 			snapshot  =  RegisterSnapshot (GetTransactionSnapshot ());
230+ 			scan  =  heap_beginscan (rel , snapshot , 0 , NULL , NULL , scan_flags );
231+ 			heap_setscanlimits (scan , first_block , last_block  -  first_block  +  1 );
232+ 			while  ((tuple  =  heap_getnext (scan , ForwardScanDirection )) !=  NULL )
233+ 			{
234+ 				CHECK_FOR_INTERRUPTS ();
235+ 			}
236+ 			heap_endscan (scan );
237+ 		} else 
238+ 		{
239+ 			ereport (INFO ,
240+ 					(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
241+ 					 errmsg ("tuple prewarm is only supported for heap relations on main fork" )));
242+ 		}
243+ 	}
213244
214245	/* Close relation, release lock. */ 
215246	relation_close (rel , AccessShareLock );
0 commit comments