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

Commit6977b8b

Browse files
committed
Port single-page btree vacuum logic to hash indexes.
This is advantageous for hash indexes for the same reasons it's goodfor btrees: it accelerates space recycling, reducing bloat.Ashutosh Sharma, reviewed by Amit Kapila and by me. A bit ofadditional hacking by me.Discussion:http://postgr.es/m/CAE9k0PkRSyzx8dOnokEpUi2A-RFZK72WN0h9DEMv_ut9q6bPRw@mail.gmail.com
1 parent2038bf4 commit6977b8b

File tree

10 files changed

+517
-17
lines changed

10 files changed

+517
-17
lines changed

‎src/backend/access/hash/README

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,10 @@ The insertion algorithm is rather similar:
284284
if we get the lock on both the buckets
285285
finish the split using algorithm mentioned below for split
286286
release the pin on old bucket and restart the insert from beginning.
287-
if current page is full, release lock but not pin, read/exclusive-lock
287+
if current page is full, first check if this page contains any dead tuples.
288+
if yes, remove dead tuples from the current page and again check for the
289+
availability of the space. If enough space found, insert the tuple else
290+
release lock but not pin, read/exclusive-lock
288291
next page; repeat as needed
289292
>> see below if no space in any page of bucket
290293
take buffer content lock in exclusive mode on metapage

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

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ typedef struct
3636
{
3737
HSpool*spool;/* NULL if not using spooling */
3838
doubleindtuples;/* # tuples accepted into index */
39+
RelationheapRel;/* heap relation descriptor */
3940
}HashBuildState;
4041

4142
staticvoidhashbuildCallback(Relationindex,
@@ -154,6 +155,7 @@ hashbuild(Relation heap, Relation index, IndexInfo *indexInfo)
154155

155156
/* prepare to build the index */
156157
buildstate.indtuples=0;
158+
buildstate.heapRel=heap;
157159

158160
/* do the heap scan */
159161
reltuples=IndexBuildHeapScan(heap,index,indexInfo, true,
@@ -162,7 +164,7 @@ hashbuild(Relation heap, Relation index, IndexInfo *indexInfo)
162164
if (buildstate.spool)
163165
{
164166
/* sort the tuples and insert them into the index */
165-
_h_indexbuild(buildstate.spool);
167+
_h_indexbuild(buildstate.spool,buildstate.heapRel);
166168
_h_spooldestroy(buildstate.spool);
167169
}
168170

@@ -218,7 +220,7 @@ hashbuildCallback(Relation index,
218220
itup=index_form_tuple(RelationGetDescr(index),
219221
index_values,index_isnull);
220222
itup->t_tid=htup->t_self;
221-
_hash_doinsert(index,itup);
223+
_hash_doinsert(index,itup,buildstate->heapRel);
222224
pfree(itup);
223225
}
224226

@@ -251,7 +253,7 @@ hashinsert(Relation rel, Datum *values, bool *isnull,
251253
itup=index_form_tuple(RelationGetDescr(rel),index_values,index_isnull);
252254
itup->t_tid=*ht_ctid;
253255

254-
_hash_doinsert(rel,itup);
256+
_hash_doinsert(rel,itup,heapRel);
255257

256258
pfree(itup);
257259

@@ -331,14 +333,24 @@ hashgettuple(IndexScanDesc scan, ScanDirection dir)
331333
if (scan->kill_prior_tuple)
332334
{
333335
/*
334-
* Yes, so mark it by setting the LP_DEAD state in the item flags.
336+
* Yes, so remember it for later. (We'll deal with all such
337+
* tuples at once right after leaving the index page or at
338+
* end of scan.) In case if caller reverses the indexscan
339+
* direction it is quite possible that the same item might
340+
* get entered multiple times. But, we don't detect that;
341+
* instead, we just forget any excess entries.
335342
*/
336-
ItemIdMarkDead(PageGetItemId(page,offnum));
343+
if (so->killedItems==NULL)
344+
so->killedItems=palloc(MaxIndexTuplesPerPage*
345+
sizeof(HashScanPosItem));
337346

338-
/*
339-
* Since this can be redone later if needed, mark as a hint.
340-
*/
341-
MarkBufferDirtyHint(buf, true);
347+
if (so->numKilled<MaxIndexTuplesPerPage)
348+
{
349+
so->killedItems[so->numKilled].heapTid=so->hashso_heappos;
350+
so->killedItems[so->numKilled].indexOffset=
351+
ItemPointerGetOffsetNumber(&(so->hashso_curpos));
352+
so->numKilled++;
353+
}
342354
}
343355

344356
/*
@@ -446,6 +458,9 @@ hashbeginscan(Relation rel, int nkeys, int norderbys)
446458
so->hashso_buc_populated= false;
447459
so->hashso_buc_split= false;
448460

461+
so->killedItems=NULL;
462+
so->numKilled=0;
463+
449464
scan->opaque=so;
450465

451466
returnscan;
@@ -461,6 +476,10 @@ hashrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
461476
HashScanOpaqueso= (HashScanOpaque)scan->opaque;
462477
Relationrel=scan->indexRelation;
463478

479+
/* Before leaving current page, deal with any killed items */
480+
if (so->numKilled>0)
481+
_hash_kill_items(scan);
482+
464483
_hash_dropscanbuf(rel,so);
465484

466485
/* set position invalid (this will cause _hash_first call) */
@@ -488,8 +507,14 @@ hashendscan(IndexScanDesc scan)
488507
HashScanOpaqueso= (HashScanOpaque)scan->opaque;
489508
Relationrel=scan->indexRelation;
490509

510+
/* Before leaving current page, deal with any killed items */
511+
if (so->numKilled>0)
512+
_hash_kill_items(scan);
513+
491514
_hash_dropscanbuf(rel,so);
492515

516+
if (so->killedItems!=NULL)
517+
pfree(so->killedItems);
493518
pfree(so);
494519
scan->opaque=NULL;
495520
}
@@ -848,6 +873,16 @@ hashbucketcleanup(Relation rel, Bucket cur_bucket, Buffer bucket_buf,
848873

849874
PageIndexMultiDelete(page,deletable,ndeletable);
850875
bucket_dirty= true;
876+
877+
/*
878+
* Let us mark the page as clean if vacuum removes the DEAD tuples
879+
* from an index page. We do this by clearing LH_PAGE_HAS_DEAD_TUPLES
880+
* flag. Clearing this flag is just a hint; replay won't redo this.
881+
*/
882+
if (tuples_removed&&*tuples_removed>0&&
883+
opaque->hasho_flag&LH_PAGE_HAS_DEAD_TUPLES)
884+
opaque->hasho_flag &= ~LH_PAGE_HAS_DEAD_TUPLES;
885+
851886
MarkBufferDirty(buf);
852887

853888
/* XLOG stuff */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp