prefetch_xid_horizon_scan_WIP.patch
application/octet-stream
Filename: prefetch_xid_horizon_scan_WIP.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/heap/heapam.c | 59 | 13 |
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 8837f83..c87fd47 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -162,6 +162,14 @@ static const struct
#define ConditionalLockTupleTuplock(rel, tup, mode) \
ConditionalLockTuple((rel), (tup), tupleLockExtraInfo[mode].hwlock)
+#ifdef USE_PREFETCH
+typedef struct
+{
+ int next_item;
+ BlockNumber cur_hblkno;
+} PrefetchState;
+#endif
+
/*
* This table maps tuple lock strength values for each particular
* MultiXactStatus value.
@@ -6990,6 +6998,45 @@ HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
/* *latestRemovedXid may still be invalid at end */
}
+#ifdef USE_PREFETCH
+/*
+ * prefetch_buffer
+ *
+ * Pre-fetch 'prefetch_count' numnber of buffers.
+ * Continues to scan the tids array from the last position that was scanned
+ * for previous pre-fetching.
+ */
+static void
+prefetch_buffer(Relation rel, PrefetchState *prefetch_state,
+ ItemPointerData *tids, int nitems, int prefetch_count)
+{
+ int count = 0;
+ BlockNumber hblkno = prefetch_state->cur_hblkno;
+ int i;
+
+ for (i = prefetch_state->next_item; i < nitems && count < prefetch_count; i++)
+ {
+ ItemPointer htid = &tids[i];
+
+ if (hblkno == InvalidBlockNumber ||
+ ItemPointerGetBlockNumber(htid) != hblkno)
+ {
+ hblkno = ItemPointerGetBlockNumber(htid);
+
+ count++;
+ PrefetchBuffer(rel, MAIN_FORKNUM, hblkno);
+ }
+ }
+
+ /*
+ * Keep track of the item pointer array position, so that next time we can
+ * continue from this position.
+ */
+ prefetch_state->next_item = i;
+ prefetch_state->cur_hblkno = hblkno;
+}
+#endif
+
/*
* Get the latestRemovedXid from the heap pages pointed at by the index
* tuples being deleted.
@@ -7011,6 +7058,7 @@ heap_compute_xid_horizon_for_tuples(Relation rel,
BlockNumber hblkno;
Buffer buf = InvalidBuffer;
Page hpage;
+ PrefetchState prefetch_state;
/*
* Sort to avoid repeated lookups for the same page, and to make it more
@@ -7023,19 +7071,10 @@ heap_compute_xid_horizon_for_tuples(Relation rel,
/* prefetch all pages */
#ifdef USE_PREFETCH
- hblkno = InvalidBlockNumber;
- for (int i = 0; i < nitems; i++)
- {
- ItemPointer htid = &tids[i];
-
- if (hblkno == InvalidBlockNumber ||
- ItemPointerGetBlockNumber(htid) != hblkno)
- {
- hblkno = ItemPointerGetBlockNumber(htid);
-
- PrefetchBuffer(rel, MAIN_FORKNUM, hblkno);
- }
- }
+ prefetch_state.next_item = 0;
+ prefetch_state.cur_hblkno = InvalidBlockNumber;
+ prefetch_buffer(rel, &prefetch_state, tids, nitems,
+ 5 /* prefetch distance ; TODO: use effective_io_concurrency */);
#endif
/* Iterate over all tids, and check their horizon */
@@ -7063,6 +7102,13 @@ heap_compute_xid_horizon_for_tuples(Relation rel,
hblkno = ItemPointerGetBlockNumber(htid);
buf = ReadBuffer(rel, hblkno);
+
+ /*
+ * Need to maintain the prefetch distance, so prefetch a page each
+ * time we read a new page.
+ */
+ prefetch_buffer(rel, &prefetch_state, tids, nitems, 1);
+
hpage = BufferGetPage(buf);
LockBuffer(buf, BUFFER_LOCK_SHARE);