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

Commitfddc2d9

Browse files
committed
Modify keys_are_unique optimization to release buffer pins before it
returns NULL. This avoids out-of-buffers failures during many-wayindexscans, as in Shraibman's complaint of 21-Mar.
1 parent346182c commitfddc2d9

File tree

2 files changed

+56
-23
lines changed

2 files changed

+56
-23
lines changed

‎src/backend/access/index/genam.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.37 2003/01/08 19:41:40 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/index/genam.c,v 1.38 2003/03/24 21:42:33 tgl Exp $
1212
*
1313
* NOTES
1414
* many of the old access method routines have been turned into
@@ -91,7 +91,7 @@ RelationGetIndexScan(Relation indexRelation,
9191

9292
scan->kill_prior_tuple= false;
9393
scan->ignore_killed_tuples= true;/* default setting */
94-
scan->keys_are_unique= false;/* may be set byamrescan */
94+
scan->keys_are_unique= false;/* may be set byindex AM */
9595
scan->got_tuple= false;
9696

9797
scan->opaque=NULL;

‎src/backend/access/index/indexam.c

Lines changed: 54 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/index/indexam.c,v 1.65 2003/03/23 23:01:03 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.66 2003/03/24 21:42:33 tgl Exp $
1212
*
1313
* INTERFACE ROUTINES
1414
*index_open- open an index relation by relation OID
@@ -311,7 +311,7 @@ index_rescan(IndexScanDesc scan, ScanKey key)
311311
GET_SCAN_PROCEDURE(rescan,amrescan);
312312

313313
scan->kill_prior_tuple= false;/* for safety */
314-
scan->keys_are_unique= false;/* may be set byamrescan */
314+
scan->keys_are_unique= false;/* may be set byindex AM */
315315
scan->got_tuple= false;
316316
scan->unique_tuple_pos=0;
317317
scan->unique_tuple_mark=0;
@@ -413,37 +413,70 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
413413

414414
SCAN_CHECKS;
415415

416+
/* Release any previously held pin */
417+
if (BufferIsValid(scan->xs_cbuf))
418+
{
419+
ReleaseBuffer(scan->xs_cbuf);
420+
scan->xs_cbuf=InvalidBuffer;
421+
}
422+
416423
/*
417-
* Can skip entering the index AM if we already got a tuple and it
418-
* must be unique. Instead, we need a "short circuit" path that
419-
* just keeps track of logical scan position (before/on/after tuple).
424+
* If we already got a tuple and it must be unique, there's no need
425+
* to make the index AM look through any additional tuples. (This can
426+
* save a useful amount of work in scenarios where there are many dead
427+
* tuples due to heavy update activity.)
420428
*
421-
* Note that we hold the pin on the single tuple's buffer throughout
422-
* the scan once we are in this state.
429+
* To do this we must keep track of the logical scan position
430+
* (before/on/after tuple). Also, we have to be sure to release scan
431+
* resources before returning NULL; if we fail to do so then a multi-index
432+
* scan can easily run the system out of free buffers. We can release
433+
* index-level resources fairly cheaply by calling index_rescan. This
434+
* means there are two persistent states as far as the index AM is
435+
* concerned: on-tuple and rescanned. If we are actually asked to
436+
* re-fetch the single tuple, we have to go through a fresh indexscan
437+
* startup, which penalizes that (infrequent) case.
423438
*/
424439
if (scan->keys_are_unique&&scan->got_tuple)
425440
{
441+
intnew_tuple_pos=scan->unique_tuple_pos;
442+
426443
if (ScanDirectionIsForward(direction))
427444
{
428-
if (scan->unique_tuple_pos <=0)
429-
scan->unique_tuple_pos++;
445+
if (new_tuple_pos <=0)
446+
new_tuple_pos++;
447+
}
448+
else
449+
{
450+
if (new_tuple_pos >=0)
451+
new_tuple_pos--;
430452
}
431-
elseif (ScanDirectionIsBackward(direction))
453+
if (new_tuple_pos==0)
432454
{
433-
if (scan->unique_tuple_pos >=0)
434-
scan->unique_tuple_pos--;
455+
/*
456+
* We are moving onto the unique tuple from having been off it.
457+
* We just fall through and let the index AM do the work. Note
458+
* we should get the right answer regardless of scan direction.
459+
*/
460+
scan->unique_tuple_pos=0;/* need to update position */
435461
}
436-
if (scan->unique_tuple_pos==0)
437-
returnheapTuple;
438462
else
439-
returnNULL;
440-
}
463+
{
464+
/*
465+
* Moving off the tuple; must do amrescan to release index-level
466+
* pins before we return NULL. Since index_rescan will reset
467+
* my state, must save and restore...
468+
*/
469+
intunique_tuple_mark=scan->unique_tuple_mark;
441470

442-
/* Release any previously held pin */
443-
if (BufferIsValid(scan->xs_cbuf))
444-
{
445-
ReleaseBuffer(scan->xs_cbuf);
446-
scan->xs_cbuf=InvalidBuffer;
471+
index_rescan(scan,NULL/* no change to key */);
472+
473+
scan->keys_are_unique= true;
474+
scan->got_tuple= true;
475+
scan->unique_tuple_pos=new_tuple_pos;
476+
scan->unique_tuple_mark=unique_tuple_mark;
477+
478+
returnNULL;
479+
}
447480
}
448481

449482
/* just make sure this is false... */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp