Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbfbcad4

Browse files
committed
tableam: bitmap table scan.
This moves bitmap heap scan support to below an optional tableamcallback. It's optional as the whole concept of bitmap heapscans isfairly block specific.This basically moves the work previously done in bitgetpage() into thenew scan_bitmap_next_block callback, and the direct poking into thebuffer done in BitmapHeapNext() into the new scan_bitmap_next_tuple()callback.The abstraction is currently somewhat leaky becausenodeBitmapHeapscan.c's prefetching and visibilitymap based logicremains - it's likely that we'll later have to move more into theAM. But it's not trivial to do so without introducing a significantamount of code duplication between the AMs, so that's a project forlater.Note that now nodeBitmapHeapscan.c and the associated node types are abit misnamed. But it's not clear whether renaming wouldn't be a cureworse than the disease. Either way, that'd be best done in a separatecommit.Author: Andres FreundReviewed-By: Robert Haas (in an older version)Discussion:https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
1 parent73c954d commitbfbcad4

File tree

7 files changed

+293
-187
lines changed

7 files changed

+293
-187
lines changed

‎src/backend/access/heap/heapam_handler.c

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,6 +1952,159 @@ heapam_estimate_rel_size(Relation rel, int32 *attr_widths,
19521952
* ------------------------------------------------------------------------
19531953
*/
19541954

1955+
staticbool
1956+
heapam_scan_bitmap_next_block(TableScanDescscan,
1957+
TBMIterateResult*tbmres)
1958+
{
1959+
HeapScanDeschscan= (HeapScanDesc)scan;
1960+
BlockNumberpage=tbmres->blockno;
1961+
Bufferbuffer;
1962+
Snapshotsnapshot;
1963+
intntup;
1964+
1965+
hscan->rs_cindex=0;
1966+
hscan->rs_ntuples=0;
1967+
1968+
/*
1969+
* Ignore any claimed entries past what we think is the end of the
1970+
* relation. It may have been extended after the start of our scan (we
1971+
* only hold an AccessShareLock, and it could be inserts from this
1972+
* backend).
1973+
*/
1974+
if (page >=hscan->rs_nblocks)
1975+
return false;
1976+
1977+
/*
1978+
* Acquire pin on the target heap page, trading in any pin we held before.
1979+
*/
1980+
hscan->rs_cbuf=ReleaseAndReadBuffer(hscan->rs_cbuf,
1981+
scan->rs_rd,
1982+
page);
1983+
hscan->rs_cblock=page;
1984+
buffer=hscan->rs_cbuf;
1985+
snapshot=scan->rs_snapshot;
1986+
1987+
ntup=0;
1988+
1989+
/*
1990+
* Prune and repair fragmentation for the whole page, if possible.
1991+
*/
1992+
heap_page_prune_opt(scan->rs_rd,buffer);
1993+
1994+
/*
1995+
* We must hold share lock on the buffer content while examining tuple
1996+
* visibility. Afterwards, however, the tuples we have found to be
1997+
* visible are guaranteed good as long as we hold the buffer pin.
1998+
*/
1999+
LockBuffer(buffer,BUFFER_LOCK_SHARE);
2000+
2001+
/*
2002+
* We need two separate strategies for lossy and non-lossy cases.
2003+
*/
2004+
if (tbmres->ntuples >=0)
2005+
{
2006+
/*
2007+
* Bitmap is non-lossy, so we just look through the offsets listed in
2008+
* tbmres; but we have to follow any HOT chain starting at each such
2009+
* offset.
2010+
*/
2011+
intcurslot;
2012+
2013+
for (curslot=0;curslot<tbmres->ntuples;curslot++)
2014+
{
2015+
OffsetNumberoffnum=tbmres->offsets[curslot];
2016+
ItemPointerDatatid;
2017+
HeapTupleDataheapTuple;
2018+
2019+
ItemPointerSet(&tid,page,offnum);
2020+
if (heap_hot_search_buffer(&tid,scan->rs_rd,buffer,snapshot,
2021+
&heapTuple,NULL, true))
2022+
hscan->rs_vistuples[ntup++]=ItemPointerGetOffsetNumber(&tid);
2023+
}
2024+
}
2025+
else
2026+
{
2027+
/*
2028+
* Bitmap is lossy, so we must examine each item pointer on the page.
2029+
* But we can ignore HOT chains, since we'll check each tuple anyway.
2030+
*/
2031+
Pagedp= (Page)BufferGetPage(buffer);
2032+
OffsetNumbermaxoff=PageGetMaxOffsetNumber(dp);
2033+
OffsetNumberoffnum;
2034+
2035+
for (offnum=FirstOffsetNumber;offnum <=maxoff;offnum=OffsetNumberNext(offnum))
2036+
{
2037+
ItemIdlp;
2038+
HeapTupleDataloctup;
2039+
boolvalid;
2040+
2041+
lp=PageGetItemId(dp,offnum);
2042+
if (!ItemIdIsNormal(lp))
2043+
continue;
2044+
loctup.t_data= (HeapTupleHeader)PageGetItem((Page)dp,lp);
2045+
loctup.t_len=ItemIdGetLength(lp);
2046+
loctup.t_tableOid=scan->rs_rd->rd_id;
2047+
ItemPointerSet(&loctup.t_self,page,offnum);
2048+
valid=HeapTupleSatisfiesVisibility(&loctup,snapshot,buffer);
2049+
if (valid)
2050+
{
2051+
hscan->rs_vistuples[ntup++]=offnum;
2052+
PredicateLockTuple(scan->rs_rd,&loctup,snapshot);
2053+
}
2054+
CheckForSerializableConflictOut(valid,scan->rs_rd,&loctup,
2055+
buffer,snapshot);
2056+
}
2057+
}
2058+
2059+
LockBuffer(buffer,BUFFER_LOCK_UNLOCK);
2060+
2061+
Assert(ntup <=MaxHeapTuplesPerPage);
2062+
hscan->rs_ntuples=ntup;
2063+
2064+
returnntup>0;
2065+
}
2066+
2067+
staticbool
2068+
heapam_scan_bitmap_next_tuple(TableScanDescscan,
2069+
TBMIterateResult*tbmres,
2070+
TupleTableSlot*slot)
2071+
{
2072+
HeapScanDeschscan= (HeapScanDesc)scan;
2073+
OffsetNumbertargoffset;
2074+
Pagedp;
2075+
ItemIdlp;
2076+
2077+
/*
2078+
* Out of range? If so, nothing more to look at on this page
2079+
*/
2080+
if (hscan->rs_cindex<0||hscan->rs_cindex >=hscan->rs_ntuples)
2081+
return false;
2082+
2083+
targoffset=hscan->rs_vistuples[hscan->rs_cindex];
2084+
dp= (Page)BufferGetPage(hscan->rs_cbuf);
2085+
lp=PageGetItemId(dp,targoffset);
2086+
Assert(ItemIdIsNormal(lp));
2087+
2088+
hscan->rs_ctup.t_data= (HeapTupleHeader)PageGetItem((Page)dp,lp);
2089+
hscan->rs_ctup.t_len=ItemIdGetLength(lp);
2090+
hscan->rs_ctup.t_tableOid=scan->rs_rd->rd_id;
2091+
ItemPointerSet(&hscan->rs_ctup.t_self,hscan->rs_cblock,targoffset);
2092+
2093+
pgstat_count_heap_fetch(scan->rs_rd);
2094+
2095+
/*
2096+
* Set up the result slot to point to this tuple. Note that the slot
2097+
* acquires a pin on the buffer.
2098+
*/
2099+
ExecStoreBufferHeapTuple(&hscan->rs_ctup,
2100+
slot,
2101+
hscan->rs_cbuf);
2102+
2103+
hscan->rs_cindex++;
2104+
2105+
return true;
2106+
}
2107+
19552108
staticbool
19562109
heapam_scan_sample_next_block(TableScanDescscan,SampleScanState*scanstate)
19572110
{
@@ -2266,6 +2419,8 @@ static const TableAmRoutine heapam_methods = {
22662419

22672420
.relation_estimate_size=heapam_estimate_rel_size,
22682421

2422+
.scan_bitmap_next_block=heapam_scan_bitmap_next_block,
2423+
.scan_bitmap_next_tuple=heapam_scan_bitmap_next_tuple,
22692424
.scan_sample_next_block=heapam_scan_sample_next_block,
22702425
.scan_sample_next_tuple=heapam_scan_sample_next_tuple
22712426
};

‎src/backend/access/table/tableamapi.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ GetTableAmRoutine(Oid amhandler)
8989
Assert(routine->index_validate_scan!=NULL);
9090
Assert(routine->relation_estimate_size!=NULL);
9191

92+
/* optional, but one callback implies presence of hte other */
93+
Assert((routine->scan_bitmap_next_block==NULL)==
94+
(routine->scan_bitmap_next_tuple==NULL));
9295
Assert(routine->scan_sample_next_block!=NULL);
9396
Assert(routine->scan_sample_next_tuple!=NULL);
9497

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp