Skip to content

Commit 49f9413

Browse files
committed
c
1 parent 165f042 commit 49f9413

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

contrib/pg_prewarm/pg_prewarm.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
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"
@@ -185,29 +186,51 @@ pg_prewarm(PG_FUNCTION_ARGS)
185186
}
186187
else if (ptype == PREWARM_BUFFER)
187188
{
188-
BlockNumber prefetch_block = first_block;
189-
Oid nspOid;
190-
int io_concurrency;
189+
if (get_relkind_objtype(rel->rd_rel->relkind) == OBJECT_TABLE && forkNumber == MAIN_FORKNUM)
190+
{
191+
uint32 scan_flags = SO_TYPE_SEQSCAN | SO_TEMP_SNAPSHOT;
192+
HeapTuple tuple;
193+
Snapshot snapshot;
194+
TableScanDesc scan;
195+
196+
elog(LOG, "pg_prewarm: SeqScan relation \"%s\" starting %ld for %ld blocks", RelationGetRelationName(rel), first_block, last_block - first_block + 1);
197+
// Use heap scan to set hint bits on every tuple. SO_ALLOW_PAGEMODE is intentionally NOT SET.
198+
// Otherwise, when a page is all visible, tuple hint bits won't be set.
199+
snapshot = RegisterSnapshot(GetTransactionSnapshot());
200+
scan = heap_beginscan(rel, snapshot, 0, NULL, NULL, scan_flags);
201+
heap_setscanlimits(scan, first_block, last_block - first_block + 1);
202+
while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
203+
{
204+
CHECK_FOR_INTERRUPTS();
205+
}
206+
heap_endscan(scan);
207+
}
208+
else
209+
{
210+
BlockNumber prefetch_block = first_block;
211+
Oid nspOid;
212+
int io_concurrency;
191213

192-
nspOid = rel->rd_rel->reltablespace;
193-
io_concurrency = get_tablespace_maintenance_io_concurrency(nspOid);
214+
nspOid = rel->rd_rel->reltablespace;
215+
io_concurrency = get_tablespace_maintenance_io_concurrency(nspOid);
194216

195-
/*
196-
* In buffer mode, we actually pull the data into shared_buffers.
197-
*/
198-
for (block = first_block; block <= last_block; ++block)
199-
{
200-
Buffer buf;
201-
BlockNumber prefetch_stop = block + Min(last_block - block + 1,
202-
io_concurrency);
203-
CHECK_FOR_INTERRUPTS();
204-
while (prefetch_block < prefetch_stop)
217+
/*
218+
* In buffer mode, we actually pull the data into shared_buffers.
219+
*/
220+
for (block = first_block; block <= last_block; ++block)
205221
{
206-
PrefetchBuffer(rel, forkNumber, prefetch_block++);
222+
Buffer buf;
223+
BlockNumber prefetch_stop = block + Min(last_block - block + 1,
224+
io_concurrency);
225+
CHECK_FOR_INTERRUPTS();
226+
while (prefetch_block < prefetch_stop)
227+
{
228+
PrefetchBuffer(rel, forkNumber, prefetch_block++);
229+
}
230+
buf = ReadBufferExtended(rel, forkNumber, block, RBM_NORMAL, NULL);
231+
ReleaseBuffer(buf);
232+
++blocks_done;
207233
}
208-
buf = ReadBufferExtended(rel, forkNumber, block, RBM_NORMAL, NULL);
209-
ReleaseBuffer(buf);
210-
++blocks_done;
211234
}
212235
}
213236

0 commit comments

Comments
 (0)