|
15 | 15 | #include <sys/stat.h> |
16 | 16 | #include <unistd.h> |
17 | 17 |
|
| 18 | +#include "access/heapam.h" |
18 | 19 | #include "access/relation.h" |
19 | 20 | #include "fmgr.h" |
20 | 21 | #include "miscadmin.h" |
@@ -185,29 +186,51 @@ pg_prewarm(PG_FUNCTION_ARGS) |
185 | 186 | } |
186 | 187 | else if (ptype == PREWARM_BUFFER) |
187 | 188 | { |
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; |
191 | 213 |
|
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); |
194 | 216 |
|
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) |
205 | 221 | { |
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; |
207 | 233 | } |
208 | | - buf = ReadBufferExtended(rel, forkNumber, block, RBM_NORMAL, NULL); |
209 | | - ReleaseBuffer(buf); |
210 | | - ++blocks_done; |
211 | 234 | } |
212 | 235 | } |
213 | 236 |
|
|
0 commit comments