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

Commit69273b8

Browse files
Use streaming read I/O in GiST vacuuming
Likec5c239e did for btree vacuuming, make GiST vacuum use theread stream API for sequentially processed pages.Because it is possible for concurrent insertions to relocate unprocessedindex entries to already vacuumed pages, GiST vacuum must backtrack andreprocess those pages. These pages are still read with explicitReadBuffer() calls.Author: Andrey M. Borodin <x4mmm@yandex-team.ru>Reviewed-by: Melanie Plageman <melanieplageman@gmail.com>Discussion:https://postgr.es/m/EFEBED92-18D1-4C0F-A4EB-CD47072EF071%40yandex-team.ru
1 parent3f850c3 commit69273b8

File tree

1 file changed

+61
-23
lines changed

1 file changed

+61
-23
lines changed

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

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include"miscadmin.h"
2323
#include"storage/indexfsm.h"
2424
#include"storage/lmgr.h"
25+
#include"storage/read_stream.h"
2526
#include"utils/memutils.h"
2627

2728
/* Working state needed by gistbulkdelete */
@@ -44,8 +45,7 @@ typedef struct
4445

4546
staticvoidgistvacuumscan(IndexVacuumInfo*info,IndexBulkDeleteResult*stats,
4647
IndexBulkDeleteCallbackcallback,void*callback_state);
47-
staticvoidgistvacuumpage(GistVacState*vstate,BlockNumberblkno,
48-
BlockNumberorig_blkno);
48+
staticvoidgistvacuumpage(GistVacState*vstate,Bufferbuffer);
4949
staticvoidgistvacuum_delete_empty_pages(IndexVacuumInfo*info,
5050
GistVacState*vstate);
5151
staticboolgistdeletepage(IndexVacuumInfo*info,IndexBulkDeleteResult*stats,
@@ -129,8 +129,9 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
129129
GistVacStatevstate;
130130
BlockNumbernum_pages;
131131
boolneedLock;
132-
BlockNumberblkno;
133132
MemoryContextoldctx;
133+
BlockRangeReadStreamPrivatep;
134+
ReadStream*stream=NULL;
134135

135136
/*
136137
* Reset fields that track information about the entire index now. This
@@ -208,7 +209,14 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
208209
*/
209210
needLock= !RELATION_IS_LOCAL(rel);
210211

211-
blkno=GIST_ROOT_BLKNO;
212+
p.current_blocknum=GIST_ROOT_BLKNO;
213+
stream=read_stream_begin_relation(READ_STREAM_FULL,
214+
info->strategy,
215+
rel,
216+
MAIN_FORKNUM,
217+
block_range_read_stream_cb,
218+
&p,
219+
0);
212220
for (;;)
213221
{
214222
/* Get the current relation length */
@@ -219,13 +227,39 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
219227
UnlockRelationForExtension(rel,ExclusiveLock);
220228

221229
/* Quit if we've scanned the whole relation */
222-
if (blkno >=num_pages)
230+
if (p.current_blocknum >=num_pages)
223231
break;
224-
/* Iterate over pages, then loop back to recheck length */
225-
for (;blkno<num_pages;blkno++)
226-
gistvacuumpage(&vstate,blkno,blkno);
232+
233+
p.last_exclusive=num_pages;
234+
235+
/* Iterate over pages, then loop back to recheck relation length */
236+
while (true)
237+
{
238+
Bufferbuf;
239+
240+
/* call vacuum_delay_point while not holding any buffer lock */
241+
vacuum_delay_point(false);
242+
243+
buf=read_stream_next_buffer(stream,NULL);
244+
245+
if (!BufferIsValid(buf))
246+
break;
247+
248+
gistvacuumpage(&vstate,buf);
249+
}
250+
251+
Assert(read_stream_next_buffer(stream,NULL)==InvalidBuffer);
252+
253+
/*
254+
* We have to reset the read stream to use it again. After returning
255+
* InvalidBuffer, the read stream API won't invoke our callback again
256+
* until the stream has been reset.
257+
*/
258+
read_stream_reset(stream);
227259
}
228260

261+
read_stream_end(stream);
262+
229263
/*
230264
* If we found any recyclable pages (and recorded them in the FSM), then
231265
* forcibly update the upper-level FSM pages to ensure that searchers can
@@ -260,34 +294,32 @@ gistvacuumscan(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
260294
/*
261295
* gistvacuumpage --- VACUUM one page
262296
*
263-
* This processes a single page for gistbulkdelete(). In some cases we
264-
* must go back and re-examine previously-scanned pages; this routine
265-
* recurses when necessary to handle that case.
266-
*
267-
* blkno is the page to process. orig_blkno is the highest block number
268-
* reached by the outer gistvacuumscan loop (the same as blkno, unless we
269-
* are recursing to re-examine a previous page).
297+
* This processes a single page for gistbulkdelete(). `buffer` contains the
298+
* page to process. In some cases we must go back and reexamine
299+
* previously-scanned pages; this routine recurses when necessary to handle
300+
* that case.
270301
*/
271302
staticvoid
272-
gistvacuumpage(GistVacState*vstate,BlockNumberblkno,BlockNumberorig_blkno)
303+
gistvacuumpage(GistVacState*vstate,Bufferbuffer)
273304
{
274305
IndexVacuumInfo*info=vstate->info;
275306
IndexBulkDeleteCallbackcallback=vstate->callback;
276307
void*callback_state=vstate->callback_state;
277308
Relationrel=info->index;
278-
Bufferbuffer;
309+
BlockNumberorig_blkno=BufferGetBlockNumber(buffer);
279310
Pagepage;
280311
BlockNumberrecurse_to;
281312

313+
/*
314+
* orig_blkno is the highest block number reached by the outer
315+
* gistvacuumscan() loop. This will be the same as blkno unless we are
316+
* recursing to reexamine a previous page.
317+
*/
318+
BlockNumberblkno=orig_blkno;
319+
282320
restart:
283321
recurse_to=InvalidBlockNumber;
284322

285-
/* call vacuum_delay_point while not holding any buffer lock */
286-
vacuum_delay_point(false);
287-
288-
buffer=ReadBufferExtended(rel,MAIN_FORKNUM,blkno,RBM_NORMAL,
289-
info->strategy);
290-
291323
/*
292324
* We are not going to stay here for a long time, aggressively grab an
293325
* exclusive lock.
@@ -450,6 +482,12 @@ gistvacuumpage(GistVacState *vstate, BlockNumber blkno, BlockNumber orig_blkno)
450482
if (recurse_to!=InvalidBlockNumber)
451483
{
452484
blkno=recurse_to;
485+
486+
/* check for vacuum delay while not holding any buffer lock */
487+
vacuum_delay_point(false);
488+
489+
buffer=ReadBufferExtended(rel,MAIN_FORKNUM,blkno,RBM_NORMAL,
490+
info->strategy);
453491
gotorestart;
454492
}
455493
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp