mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +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:
@ -1654,8 +1654,8 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
|
||||
/*
|
||||
* heap_get_latest_tid - get the latest tid of a specified tuple
|
||||
*
|
||||
* Actually, this gets the latest version that is visible according to
|
||||
* the passed snapshot. You can pass SnapshotDirty to get the very latest,
|
||||
* Actually, this gets the latest version that is visible according to the
|
||||
* scan's snapshot. Create a scan using SnapshotDirty to get the very latest,
|
||||
* possibly uncommitted version.
|
||||
*
|
||||
* *tid is both an input and an output parameter: it is updated to
|
||||
@ -1663,28 +1663,20 @@ heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer,
|
||||
* if no version of the row passes the snapshot test.
|
||||
*/
|
||||
void
|
||||
heap_get_latest_tid(Relation relation,
|
||||
Snapshot snapshot,
|
||||
heap_get_latest_tid(TableScanDesc sscan,
|
||||
ItemPointer tid)
|
||||
{
|
||||
BlockNumber blk;
|
||||
Relation relation = sscan->rs_rd;
|
||||
Snapshot snapshot = sscan->rs_snapshot;
|
||||
ItemPointerData ctid;
|
||||
TransactionId priorXmax;
|
||||
|
||||
/* this is to avoid Assert failures on bad input */
|
||||
if (!ItemPointerIsValid(tid))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Since this can be called with user-supplied TID, don't trust the input
|
||||
* too much. (RelationGetNumberOfBlocks is an expensive check, so we
|
||||
* don't check t_ctid links again this way. Note that it would not do to
|
||||
* call it just once and save the result, either.)
|
||||
* table_get_latest_tid verified that the passed in tid is valid. Assume
|
||||
* that t_ctid links are valid however - there shouldn't be invalid ones
|
||||
* in the table.
|
||||
*/
|
||||
blk = ItemPointerGetBlockNumber(tid);
|
||||
if (blk >= RelationGetNumberOfBlocks(relation))
|
||||
elog(ERROR, "block number %u is out of range for relation \"%s\"",
|
||||
blk, RelationGetRelationName(relation));
|
||||
Assert(ItemPointerIsValid(tid));
|
||||
|
||||
/*
|
||||
* Loop to chase down t_ctid links. At top of loop, ctid is the tuple we
|
||||
|
Reference in New Issue
Block a user