1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-21 10:42:50 +03:00

tableam: Avoid relying on relation size to determine validity of tids.

Instead add a tableam callback to do so. To avoid adding per
validation overhead, pass a scan to tuple_tid_valid. In heap's case
we'd otherwise incurred a RelationGetNumberOfBlocks() call for each
tid - which'd have added noticable overhead to nodeTidscan.c.

Author: Andres Freund
Reviewed-By: Ashwin Agrawal
Discussion: https://postgr.es/m/20190515185447.gno2jtqxyktylyvs@alap3.anarazel.de
This commit is contained in:
Andres Freund
2019-05-17 18:52:01 -07:00
parent 7f44ede594
commit 147e3722f7
7 changed files with 129 additions and 57 deletions

View File

@@ -134,8 +134,7 @@ extern bool heap_hot_search_buffer(ItemPointer tid, Relation relation,
Buffer buffer, Snapshot snapshot, HeapTuple heapTuple,
bool *all_dead, bool first_call);
extern void heap_get_latest_tid(Relation relation, Snapshot snapshot,
ItemPointer tid);
extern void heap_get_latest_tid(TableScanDesc scan, ItemPointer tid);
extern void setLastTid(const ItemPointer tid);
extern BulkInsertState GetBulkInsertState(void);

View File

@@ -308,12 +308,17 @@ typedef struct TableAmRoutine
Snapshot snapshot,
TupleTableSlot *slot);
/*
* Is tid valid for a scan of this relation.
*/
bool (*tuple_tid_valid) (TableScanDesc scan,
ItemPointer tid);
/*
* Return the latest version of the tuple at `tid`, by updating `tid` to
* point at the newest version.
*/
void (*tuple_get_latest_tid) (Relation rel,
Snapshot snapshot,
void (*tuple_get_latest_tid) (TableScanDesc scan,
ItemPointer tid);
/*
@@ -548,10 +553,10 @@ typedef struct TableAmRoutine
/*
* See table_relation_size().
*
* Note that currently a few callers use the MAIN_FORKNUM size to vet the
* validity of tids (e.g. nodeTidscans.c), and others use it to figure out
* the range of potentially interesting blocks (brin, analyze). The
* abstraction around this will need to be improved in the near future.
* Note that currently a few callers use the MAIN_FORKNUM size to figure
* out the range of potentially interesting blocks (brin, analyze). It's
* probable that we'll need to revise the interface for those at some
* point.
*/
uint64 (*relation_size) (Relation rel, ForkNumber forkNumber);
@@ -985,15 +990,25 @@ table_fetch_row_version(Relation rel,
return rel->rd_tableam->tuple_fetch_row_version(rel, tid, snapshot, slot);
}
/*
* Verify that `tid` is a potentially valid tuple identifier. That doesn't
* mean that the pointed to row needs to exist or be visible, but that
* attempting to fetch the row (e.g. with table_get_latest_tid() or
* table_fetch_row_version()) should not error out if called with that tid.
*
* `scan` needs to have been started via table_beginscan().
*/
static inline bool
table_tuple_tid_valid(TableScanDesc scan, ItemPointer tid)
{
return scan->rs_rd->rd_tableam->tuple_tid_valid(scan, tid);
}
/*
* Return the latest version of the tuple at `tid`, by updating `tid` to
* point at the newest version.
*/
static inline void
table_get_latest_tid(Relation rel, Snapshot snapshot, ItemPointer tid)
{
rel->rd_tableam->tuple_get_latest_tid(rel, snapshot, tid);
}
extern void table_get_latest_tid(TableScanDesc scan, ItemPointer tid);
/*
* Return true iff tuple in slot satisfies the snapshot.