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

Commit3f4d488

Browse files
committed
Mark index entries "killed" when they are no longer visible to any
transaction, so as to avoid returning them out of the index AM. Savesrepeated heap_fetch operations on frequently-updated rows. Also detectqueries on unique keys (equality to all columns of a unique index), anddon't bother continuing scan once we have found first match.Killing is implemented in the btree and hash AMs, but not yet in rtreeor gist, because there isn't an equally convenient place to do it inthose AMs (the outer amgetnext routine can't do it without re-pinningthe index page).Did some small cleanup on APIs of HeapTupleSatisfies, heap_fetch, andindex_insert to make this a little easier.
1 parent2f2d057 commit3f4d488

File tree

30 files changed

+498
-273
lines changed

30 files changed

+498
-273
lines changed

‎src/backend/access/gist/gist.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.92 2002/05/20 23:51:40 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.93 2002/05/24 18:57:55 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -294,9 +294,9 @@ gistinsert(PG_FUNCTION_ARGS)
294294
Datum*datum= (Datum*)PG_GETARG_POINTER(1);
295295
char*nulls= (char*)PG_GETARG_POINTER(2);
296296
ItemPointerht_ctid= (ItemPointer)PG_GETARG_POINTER(3);
297-
298297
#ifdefNOT_USED
299298
RelationheapRel= (Relation)PG_GETARG_POINTER(4);
299+
boolcheckUnique=PG_GETARG_BOOL(5);
300300
#endif
301301
InsertIndexResultres;
302302
IndexTupleitup;
@@ -1607,6 +1607,8 @@ gistbulkdelete(PG_FUNCTION_ARGS)
16071607

16081608
/* walk through the entire index */
16091609
iscan=index_beginscan(NULL,rel,SnapshotAny,0, (ScanKey)NULL);
1610+
/* including killed tuples */
1611+
iscan->ignore_killed_tuples= false;
16101612

16111613
while (index_getnext_indexitem(iscan,ForwardScanDirection))
16121614
{

‎src/backend/access/hash/hash.c

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.57 2002/05/20 23:51:41 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/hash/hash.c,v 1.58 2002/05/24 18:57:55 tgl Exp $
1212
*
1313
* NOTES
1414
* This file contains only the public interface routines.
@@ -166,8 +166,8 @@ hashinsert(PG_FUNCTION_ARGS)
166166
ItemPointerht_ctid= (ItemPointer)PG_GETARG_POINTER(3);
167167
#ifdefNOT_USED
168168
RelationheapRel= (Relation)PG_GETARG_POINTER(4);
169+
boolcheckUnique=PG_GETARG_BOOL(5);
169170
#endif
170-
171171
InsertIndexResultres;
172172
HashItemhitem;
173173
IndexTupleitup;
@@ -210,19 +210,59 @@ hashgettuple(PG_FUNCTION_ARGS)
210210
{
211211
IndexScanDescscan= (IndexScanDesc)PG_GETARG_POINTER(0);
212212
ScanDirectiondir= (ScanDirection)PG_GETARG_INT32(1);
213+
HashScanOpaqueso= (HashScanOpaque)scan->opaque;
214+
Pagepage;
215+
OffsetNumberoffnum;
213216
boolres;
214217

215218
/*
216219
* If we've already initialized this scan, we can just advance it in
217220
* the appropriate direction. If we haven't done so yet, we call a
218221
* routine to get the first item in the scan.
219222
*/
220-
221223
if (ItemPointerIsValid(&(scan->currentItemData)))
224+
{
225+
/*
226+
* Check to see if we should kill the previously-fetched tuple.
227+
*/
228+
if (scan->kill_prior_tuple)
229+
{
230+
/*
231+
* Yes, so mark it by setting the LP_DELETE bit in the item flags.
232+
*/
233+
offnum=ItemPointerGetOffsetNumber(&(scan->currentItemData));
234+
page=BufferGetPage(so->hashso_curbuf);
235+
PageGetItemId(page,offnum)->lp_flags |=LP_DELETE;
236+
/*
237+
* Since this can be redone later if needed, it's treated the
238+
* same as a commit-hint-bit status update for heap tuples:
239+
* we mark the buffer dirty but don't make a WAL log entry.
240+
*/
241+
SetBufferCommitInfoNeedsSave(so->hashso_curbuf);
242+
}
243+
/*
244+
* Now continue the scan.
245+
*/
222246
res=_hash_next(scan,dir);
247+
}
223248
else
224249
res=_hash_first(scan,dir);
225250

251+
/*
252+
* Skip killed tuples if asked to.
253+
*/
254+
if (scan->ignore_killed_tuples)
255+
{
256+
while (res)
257+
{
258+
offnum=ItemPointerGetOffsetNumber(&(scan->currentItemData));
259+
page=BufferGetPage(so->hashso_curbuf);
260+
if (!ItemIdDeleted(PageGetItemId(page,offnum)))
261+
break;
262+
res=_hash_next(scan,dir);
263+
}
264+
}
265+
226266
PG_RETURN_BOOL(res);
227267
}
228268

@@ -418,6 +458,8 @@ hashbulkdelete(PG_FUNCTION_ARGS)
418458

419459
/* walk through the entire index */
420460
iscan=index_beginscan(NULL,rel,SnapshotAny,0, (ScanKey)NULL);
461+
/* including killed tuples */
462+
iscan->ignore_killed_tuples= false;
421463

422464
while (index_getnext_indexitem(iscan,ForwardScanDirection))
423465
{

‎src/backend/access/hash/hashscan.c

Lines changed: 36 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.26 2002/05/20 23:51:41 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashscan.c,v 1.27 2002/05/24 18:57:55 tgl Exp $
1212
*
1313
* NOTES
1414
* Because we can be doing an index scan on a relation while we
@@ -32,8 +32,6 @@
3232

3333
#include"access/hash.h"
3434

35-
staticvoid_hash_scandel(IndexScanDescscan,BlockNumberblkno,OffsetNumberoffno);
36-
staticbool_hash_scantouched(IndexScanDescscan,BlockNumberblkno,OffsetNumberoffno);
3735

3836
typedefstructHashScanListData
3937
{
@@ -46,6 +44,10 @@ typedef HashScanListData *HashScanList;
4644
staticHashScanListHashScans= (HashScanList)NULL;
4745

4846

47+
staticvoid_hash_scandel(IndexScanDescscan,
48+
BlockNumberblkno,OffsetNumberoffno);
49+
50+
4951
/*
5052
* AtEOXact_hash() --- clean up hash subsystem at xact abort or commit.
5153
*
@@ -129,63 +131,51 @@ static void
129131
_hash_scandel(IndexScanDescscan,BlockNumberblkno,OffsetNumberoffno)
130132
{
131133
ItemPointercurrent;
134+
ItemPointermark;
132135
Bufferbuf;
133136
Buffermetabuf;
134137
HashScanOpaqueso;
135138

136-
if (!_hash_scantouched(scan,blkno,offno))
137-
return;
138-
139-
metabuf=_hash_getbuf(scan->indexRelation,HASH_METAPAGE,HASH_READ);
140-
141139
so= (HashScanOpaque)scan->opaque;
142-
buf=so->hashso_curbuf;
143-
144140
current=&(scan->currentItemData);
141+
mark=&(scan->currentMarkData);
142+
145143
if (ItemPointerIsValid(current)
146144
&&ItemPointerGetBlockNumber(current)==blkno
147145
&&ItemPointerGetOffsetNumber(current) >=offno)
148146
{
147+
metabuf=_hash_getbuf(scan->indexRelation,HASH_METAPAGE,HASH_READ);
148+
buf=so->hashso_curbuf;
149149
_hash_step(scan,&buf,BackwardScanDirection,metabuf);
150-
so->hashso_curbuf=buf;
151150
}
152151

153-
current=&(scan->currentMarkData);
154-
if (ItemPointerIsValid(current)
155-
&&ItemPointerGetBlockNumber(current)==blkno
156-
&&ItemPointerGetOffsetNumber(current) >=offno)
152+
if (ItemPointerIsValid(mark)
153+
&&ItemPointerGetBlockNumber(mark)==blkno
154+
&&ItemPointerGetOffsetNumber(mark) >=offno)
157155
{
158-
ItemPointerDatatmp;
159-
160-
tmp=*current;
161-
*current=scan->currentItemData;
162-
scan->currentItemData=tmp;
156+
/*
157+
* The idea here is to exchange the current and mark positions,
158+
* then step backwards (affecting current), then exchange again.
159+
*/
160+
ItemPointerDatatmpitem;
161+
Buffertmpbuf;
162+
163+
tmpitem=*mark;
164+
*mark=*current;
165+
*current=tmpitem;
166+
tmpbuf=so->hashso_mrkbuf;
167+
so->hashso_mrkbuf=so->hashso_curbuf;
168+
so->hashso_curbuf=tmpbuf;
169+
170+
metabuf=_hash_getbuf(scan->indexRelation,HASH_METAPAGE,HASH_READ);
171+
buf=so->hashso_curbuf;
163172
_hash_step(scan,&buf,BackwardScanDirection,metabuf);
164-
so->hashso_mrkbuf=buf;
165-
tmp=*current;
166-
*current=scan->currentItemData;
167-
scan->currentItemData=tmp;
168-
}
169-
}
170173

171-
staticbool
172-
_hash_scantouched(IndexScanDescscan,
173-
BlockNumberblkno,
174-
OffsetNumberoffno)
175-
{
176-
ItemPointercurrent;
177-
178-
current=&(scan->currentItemData);
179-
if (ItemPointerIsValid(current)
180-
&&ItemPointerGetBlockNumber(current)==blkno
181-
&&ItemPointerGetOffsetNumber(current) >=offno)
182-
return true;
183-
184-
current=&(scan->currentMarkData);
185-
if (ItemPointerIsValid(current)
186-
&&ItemPointerGetBlockNumber(current)==blkno
187-
&&ItemPointerGetOffsetNumber(current) >=offno)
188-
return true;
189-
190-
return false;
174+
tmpitem=*mark;
175+
*mark=*current;
176+
*current=tmpitem;
177+
tmpbuf=so->hashso_mrkbuf;
178+
so->hashso_mrkbuf=so->hashso_curbuf;
179+
so->hashso_curbuf=tmpbuf;
180+
}
191181
}

‎src/backend/access/hash/hashsearch.c

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.28 2002/05/20 23:51:41 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/hash/hashsearch.c,v 1.29 2002/05/24 18:57:55 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -54,10 +54,10 @@ _hash_search(Relation rel,
5454
*_hash_next() -- Get the next item in a scan.
5555
*
5656
*On entry, we have a valid currentItemData in the scan, and a
57-
*read lock on the page that contains that item.We do not have
58-
*the page pinned.Wereturn the next item in the scan.On
59-
*exit, we have the page containing the next item locked but not
60-
*pinned.
57+
*pin andread lock on the page that contains that item.
58+
*Wefind the next item in the scan, if any.
59+
*On successexit, we have the page containing the next item
60+
*pinned and locked.
6161
*/
6262
bool
6363
_hash_next(IndexScanDescscan,ScanDirectiondir)
@@ -74,25 +74,12 @@ _hash_next(IndexScanDesc scan, ScanDirection dir)
7474

7575
rel=scan->indexRelation;
7676
so= (HashScanOpaque)scan->opaque;
77-
current=&(scan->currentItemData);
78-
79-
metabuf=_hash_getbuf(rel,HASH_METAPAGE,HASH_READ);
80-
81-
/*
82-
* XXX 10 may 91: somewhere there's a bug in our management of the
83-
* cached buffer for this scan. wei discovered it. the following is
84-
* a workaround so he can work until i figure out what's going on.
85-
*/
86-
87-
if (!BufferIsValid(so->hashso_curbuf))
88-
{
89-
so->hashso_curbuf=_hash_getbuf(rel,
90-
ItemPointerGetBlockNumber(current),
91-
HASH_READ);
92-
}
9377

9478
/* we still have the buffer pinned and locked */
9579
buf=so->hashso_curbuf;
80+
Assert(BufferIsValid(buf));
81+
82+
metabuf=_hash_getbuf(rel,HASH_METAPAGE,HASH_READ);
9683

9784
/*
9885
* step to next valid tuple. note that _hash_step releases our lock

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp