diff options
| author | Andres Freund <andres@anarazel.de> | 2019-03-26 14:41:46 -0700 |
|---|---|---|
| committer | Andres Freund <andres@anarazel.de> | 2019-03-26 16:52:54 -0700 |
| commit | 558a9165e081d1936573e5a7d576f5febd7fb55a (patch) | |
| tree | 9403d15cb5fdaaf019b57b797c21cbc0db31a733 /src/include | |
| parent | 126d631222328d3def7910934bfa9cbdc99d79cc (diff) | |
Compute XID horizon for page level index vacuum on primary.
Previously the xid horizon was only computed during WAL replay. That
had two major problems:
1) It relied on knowing what the table pointed to looks like. That was
easy enough before the introducing of tableam (we knew it had to be
heap, although some trickery around logging the heap relfilenodes
was required). But to properly handle table AMs we need
per-database catalog access to look up the AM handler, which
recovery doesn't allow.
2) Not knowing the xid horizon also makes it hard to support logical
decoding on standbys. When on a catalog table, we need to be able
to conflict with slots that have an xid horizon that's too old. But
computing the horizon by visiting the heap only works once
consistency is reached, but we always need to be able to detect
conflicts.
There's also a secondary problem, in that the current method performs
redundant work on every standby. But that's counterbalanced by
potentially computing the value when not necessary (either because
there's no standby, or because there's no connected backends).
Solve 1) and 2) by moving computation of the xid horizon to the
primary and by involving tableam in the computation of the horizon.
To address the potentially increased overhead, increase the efficiency
of the xid horizon computation for heap by sorting the tids, and
eliminating redundant buffer accesses. When prefetching is available,
additionally perform prefetching of buffers. As this is more of a
maintenance task, rather than something routinely done in every read
only query, we add an arbitrary 10 to the effective concurrency -
thereby using IO concurrency, when not globally enabled. That's
possibly not the perfect formula, but seems good enough for now.
Bumps WAL format, as latestRemovedXid is now part of the records, and
the heap's relfilenode isn't anymore.
Author: Andres Freund, Amit Khandekar, Robert Haas
Reviewed-By: Robert Haas
Discussion:
https://postgr.es/m/20181212204154.nsxf3gzqv3gesl32@alap3.anarazel.de
https://postgr.es/m/20181214014235.dal5ogljs3bmlq44@alap3.anarazel.de
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/access/genam.h | 5 | ||||
| -rw-r--r-- | src/include/access/hash_xlog.h | 2 | ||||
| -rw-r--r-- | src/include/access/heapam.h | 4 | ||||
| -rw-r--r-- | src/include/access/nbtxlog.h | 3 | ||||
| -rw-r--r-- | src/include/access/tableam.h | 19 | ||||
| -rw-r--r-- | src/include/access/xlog_internal.h | 2 |
6 files changed, 31 insertions, 4 deletions
diff --git a/src/include/access/genam.h b/src/include/access/genam.h index cad66513f62..70c7351a08c 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -188,6 +188,11 @@ extern IndexScanDesc RelationGetIndexScan(Relation indexRelation, extern void IndexScanEnd(IndexScanDesc scan); extern char *BuildIndexValueDescription(Relation indexRelation, Datum *values, bool *isnull); +extern TransactionId index_compute_xid_horizon_for_tuples(Relation irel, + Relation hrel, + Buffer ibuf, + OffsetNumber *itemnos, + int nitems); /* * heap-or-index access to system catalogs (in genam.c) diff --git a/src/include/access/hash_xlog.h b/src/include/access/hash_xlog.h index 9cef1b7c25d..53b682c56ef 100644 --- a/src/include/access/hash_xlog.h +++ b/src/include/access/hash_xlog.h @@ -263,7 +263,7 @@ typedef struct xl_hash_init_bitmap_page */ typedef struct xl_hash_vacuum_one_page { - RelFileNode hnode; + TransactionId latestRemovedXid; int ntuples; /* TARGET OFFSET NUMBERS FOLLOW AT THE END */ diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h index 3773a4df853..4c077755d54 100644 --- a/src/include/access/heapam.h +++ b/src/include/access/heapam.h @@ -174,6 +174,10 @@ extern void simple_heap_update(Relation relation, ItemPointer otid, extern void heap_sync(Relation relation); +extern TransactionId heap_compute_xid_horizon_for_tuples(Relation rel, + ItemPointerData *items, + int nitems); + /* in heap/pruneheap.c */ extern void heap_page_prune_opt(Relation relation, Buffer buffer); extern int heap_page_prune(Relation relation, Buffer buffer, diff --git a/src/include/access/nbtxlog.h b/src/include/access/nbtxlog.h index 6320a0098ff..9beccc86eaf 100644 --- a/src/include/access/nbtxlog.h +++ b/src/include/access/nbtxlog.h @@ -126,8 +126,7 @@ typedef struct xl_btree_split */ typedef struct xl_btree_delete { - RelFileNode hnode; /* RelFileNode of the heap the index currently - * points at */ + TransactionId latestRemovedXid; int nitems; /* TARGET OFFSET NUMBERS FOLLOW AT THE END */ diff --git a/src/include/access/tableam.h b/src/include/access/tableam.h index 4699335cdfd..37890dc2f5c 100644 --- a/src/include/access/tableam.h +++ b/src/include/access/tableam.h @@ -299,6 +299,12 @@ typedef struct TableAmRoutine TupleTableSlot *slot, Snapshot snapshot); + /* see table_compute_xid_horizon_for_tuples() */ + TransactionId (*compute_xid_horizon_for_tuples) (Relation rel, + ItemPointerData *items, + int nitems); + + /* ------------------------------------------------------------------------ * Manipulations of physical tuples. * ------------------------------------------------------------------------ @@ -689,6 +695,19 @@ table_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, Snapshot snap return rel->rd_tableam->tuple_satisfies_snapshot(rel, slot, snapshot); } +/* + * Compute the newest xid among the tuples pointed to by items. This is used + * to compute what snapshots to conflict with when replaying WAL records for + * page-level index vacuums. + */ +static inline TransactionId +table_compute_xid_horizon_for_tuples(Relation rel, + ItemPointerData *items, + int nitems) +{ + return rel->rd_tableam->compute_xid_horizon_for_tuples(rel, items, nitems); +} + /* ---------------------------------------------------------------------------- * Functions for manipulations of physical tuples. diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index 42d1065d1e0..8b1348c36db 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -31,7 +31,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD099 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD100 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { |
