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

Commit2f27f8c

Browse files
committed
Provide ReadRecentBuffer() to re-pin buffers by ID.
If you know the ID of a buffer that recently held a block that you wouldlike to pin, this function can be used check if it's still there. Itcan be used to avoid a second lookup in the buffer mapping table afterPrefetchBuffer() reports a cache hit.Reviewed-by: Andres Freund <andres@anarazel.de>Discussion:https://postgr.es/m/CA+hUKGJ4VJN8ttxScUFM8dOKX0BrBiboo5uz1cq=AovOddfHpA@mail.gmail.com
1 parent0827e8a commit2f27f8c

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

‎src/backend/storage/buffer/bufmgr.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,84 @@ PrefetchBuffer(Relation reln, ForkNumber forkNum, BlockNumber blockNum)
610610
}
611611
}
612612

613+
/*
614+
* ReadRecentBuffer -- try to pin a block in a recently observed buffer
615+
*
616+
* Compared to ReadBuffer(), this avoids a buffer mapping lookup when it's
617+
* successful. Return true if the buffer is valid and still has the expected
618+
* tag. In that case, the buffer is pinned and the usage count is bumped.
619+
*/
620+
bool
621+
ReadRecentBuffer(RelFileNodernode,ForkNumberforkNum,BlockNumberblockNum,
622+
Bufferrecent_buffer)
623+
{
624+
BufferDesc*bufHdr;
625+
BufferTagtag;
626+
uint32buf_state;
627+
boolhave_private_ref;
628+
629+
Assert(BufferIsValid(recent_buffer));
630+
631+
ResourceOwnerEnlargeBuffers(CurrentResourceOwner);
632+
ReservePrivateRefCountEntry();
633+
INIT_BUFFERTAG(tag,rnode,forkNum,blockNum);
634+
635+
if (BufferIsLocal(recent_buffer))
636+
{
637+
bufHdr=GetBufferDescriptor(-recent_buffer-1);
638+
buf_state=pg_atomic_read_u32(&bufHdr->state);
639+
640+
/* Is it still valid and holding the right tag? */
641+
if ((buf_state&BM_VALID)&&BUFFERTAGS_EQUAL(tag,bufHdr->tag))
642+
{
643+
/* Bump local buffer's ref and usage counts. */
644+
ResourceOwnerRememberBuffer(CurrentResourceOwner,recent_buffer);
645+
LocalRefCount[-recent_buffer-1]++;
646+
if (BUF_STATE_GET_USAGECOUNT(buf_state)<BM_MAX_USAGE_COUNT)
647+
pg_atomic_write_u32(&bufHdr->state,
648+
buf_state+BUF_USAGECOUNT_ONE);
649+
650+
return true;
651+
}
652+
}
653+
else
654+
{
655+
bufHdr=GetBufferDescriptor(recent_buffer-1);
656+
have_private_ref=GetPrivateRefCount(recent_buffer)>0;
657+
658+
/*
659+
* Do we already have this buffer pinned with a private reference? If
660+
* so, it must be valid and it is safe to check the tag without
661+
* locking. If not, we have to lock the header first and then check.
662+
*/
663+
if (have_private_ref)
664+
buf_state=pg_atomic_read_u32(&bufHdr->state);
665+
else
666+
buf_state=LockBufHdr(bufHdr);
667+
668+
if ((buf_state&BM_VALID)&&BUFFERTAGS_EQUAL(tag,bufHdr->tag))
669+
{
670+
/*
671+
* It's now safe to pin the buffer. We can't pin first and ask
672+
* questions later, because because it might confuse code paths
673+
* like InvalidateBuffer() if we pinned a random non-matching
674+
* buffer.
675+
*/
676+
if (have_private_ref)
677+
PinBuffer(bufHdr,NULL);/* bump pin count */
678+
else
679+
PinBuffer_Locked(bufHdr);/* pin for first time */
680+
681+
return true;
682+
}
683+
684+
/* If we locked the header above, now unlock. */
685+
if (!have_private_ref)
686+
UnlockBufHdr(bufHdr,buf_state);
687+
}
688+
689+
return false;
690+
}
613691

614692
/*
615693
* ReadBuffer -- a shorthand for ReadBufferExtended, for reading from main

‎src/include/storage/bufmgr.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ extern PrefetchBufferResult PrefetchSharedBuffer(struct SMgrRelationData *smgr_r
176176
BlockNumberblockNum);
177177
externPrefetchBufferResultPrefetchBuffer(Relationreln,ForkNumberforkNum,
178178
BlockNumberblockNum);
179+
externboolReadRecentBuffer(RelFileNodernode,ForkNumberforkNum,
180+
BlockNumberblockNum,Bufferrecent_buffer);
179181
externBufferReadBuffer(Relationreln,BlockNumberblockNum);
180182
externBufferReadBufferExtended(Relationreln,ForkNumberforkNum,
181183
BlockNumberblockNum,ReadBufferModemode,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp