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

Commitdd72882

Browse files
committed
Fix locking problem in _hash_squeezebucket() / _hash_freeovflpage().
A bucket squeeze operation needs to lock each page of the bucketbefore releasing the prior page, but the previous coding fumbled thelocking when freeing an overflow page during a bucket squeezeoperation. Commit6d46f47introduced this bug.Amit Kapila, with help from Kuntal Ghosh and Dilip Kumar, afteran initial trouble report by Jeff Janes. Reviewed by me. I alsofixed a problem with a comment.
1 parent668dbbe commitdd72882

File tree

2 files changed

+13
-30
lines changed

2 files changed

+13
-30
lines changed

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

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -377,12 +377,11 @@ _hash_firstfreebit(uint32 map)
377377
*NB: caller must not hold lock on metapage, nor on page, that's next to
378378
*ovflbuf in the bucket chain. We don't acquire the lock on page that's
379379
*prior to ovflbuf in chain if it is same as wbuf because the caller already
380-
*has a lock on same. This function releases the lock on wbuf and caller
381-
*is responsible for releasing the pin on same.
380+
*has a lock on same.
382381
*/
383382
BlockNumber
384383
_hash_freeovflpage(Relationrel,Bufferovflbuf,Bufferwbuf,
385-
boolwbuf_dirty,BufferAccessStrategybstrategy)
384+
BufferAccessStrategybstrategy)
386385
{
387386
HashMetaPagemetap;
388387
Buffermetabuf;
@@ -447,24 +446,10 @@ _hash_freeovflpage(Relation rel, Buffer ovflbuf, Buffer wbuf,
447446
Assert(prevopaque->hasho_bucket==bucket);
448447
prevopaque->hasho_nextblkno=nextblkno;
449448

449+
MarkBufferDirty(prevbuf);
450450
if (prevblkno!=writeblkno)
451-
{
452-
MarkBufferDirty(prevbuf);
453451
_hash_relbuf(rel,prevbuf);
454-
}
455-
else
456-
{
457-
/* ensure to mark prevbuf as dirty */
458-
wbuf_dirty= true;
459-
}
460452
}
461-
462-
/* write and unlock the write buffer */
463-
if (wbuf_dirty)
464-
_hash_chgbufaccess(rel,wbuf,HASH_WRITE,HASH_NOLOCK);
465-
else
466-
_hash_chgbufaccess(rel,wbuf,HASH_READ,HASH_NOLOCK);
467-
468453
if (BlockNumberIsValid(nextblkno))
469454
{
470455
Buffernextbuf=_hash_getbuf_with_strategy(rel,
@@ -783,30 +768,28 @@ _hash_squeezebucket(Relation rel,
783768
* Tricky point here: if our read and write pages are adjacent in the
784769
* bucket chain, our write lock on wbuf will conflict with
785770
* _hash_freeovflpage's attempt to update the sibling links of the
786-
* removed page. In that case, we don't need to lock it again and we
787-
* always release the lock on wbuf in _hash_freeovflpage and then
788-
* retake it again here. This will not only simplify the code, but is
789-
* required to atomically log the changes which will be helpful when
790-
* we write WAL for hash indexes.
771+
* removed page. In that case, we don't need to lock it again.
791772
*/
792773
rblkno=ropaque->hasho_prevblkno;
793774
Assert(BlockNumberIsValid(rblkno));
794775

795776
/* free this overflow page (releases rbuf) */
796-
_hash_freeovflpage(rel,rbuf,wbuf,wbuf_dirty,bstrategy);
777+
_hash_freeovflpage(rel,rbuf,wbuf,bstrategy);
778+
779+
if (wbuf_dirty)
780+
MarkBufferDirty(wbuf);
797781

798782
/* are we freeing the page adjacent to wbuf? */
799783
if (rblkno==wblkno)
800784
{
801785
/* retain the pin on primary bucket page till end of bucket scan */
802-
if (wblkno!=bucket_blkno)
803-
_hash_dropbuf(rel,wbuf);
786+
if (wblkno==bucket_blkno)
787+
_hash_chgbufaccess(rel,wbuf,HASH_READ,HASH_NOLOCK);
788+
else
789+
_hash_relbuf(rel,wbuf);
804790
return;
805791
}
806792

807-
/* lock the overflow page being written, then get the previous one */
808-
_hash_chgbufaccess(rel,wbuf,HASH_NOLOCK,HASH_WRITE);
809-
810793
rbuf=_hash_getbuf_with_strategy(rel,
811794
rblkno,
812795
HASH_WRITE,

‎src/include/access/hash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ extern OffsetNumber _hash_pgaddtup(Relation rel, Buffer buf,
314314
/* hashovfl.c */
315315
externBuffer_hash_addovflpage(Relationrel,Buffermetabuf,Bufferbuf,boolretain_pin);
316316
externBlockNumber_hash_freeovflpage(Relationrel,Bufferovflbuf,Bufferwbuf,
317-
boolwbuf_dirty,BufferAccessStrategybstrategy);
317+
BufferAccessStrategybstrategy);
318318
externvoid_hash_initbitmap(Relationrel,HashMetaPagemetap,
319319
BlockNumberblkno,ForkNumberforkNum);
320320
externvoid_hash_squeezebucket(Relationrel,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp