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

Commit9660906

Browse files
committed
Add routines for marking buffers dirty efficiently
This commit introduces new internal bufmgr routines for marking sharedbuffers as dirty:* MarkDirtyUnpinnedBuffer()* MarkDirtyRelUnpinnedBuffers()* MarkDirtyAllUnpinnedBuffers()These functions provide an efficient mechanism to respectively mark onebuffer, all the buffers of a relation, or the entire shared buffer poolas dirty, something that can be useful to force patterns for thecheckpointer. MarkDirtyUnpinnedBufferInternal(), an extra routine, isused by these three, to mark as dirty an unpinned buffer.They are intended as developer tools to manipulate buffer dirtiness inbulk, and will be used in a follow-up commit.Author: Nazir Bilal Yavuz <byavuz81@gmail.com>Reviewed-by: Andres Freund <andres@anarazel.de>Reviewed-by: Aidar Imamov <a.imamov@postgrespro.ru>Reviewed-by: Amit Kapila <amit.kapila16@gmail.com>Reviewed-by: Joseph Koshakow <koshy44@gmail.com>Reviewed-by: Michael Paquier <michael@paquier.xyz>Reviewed-by: Yuhang Qiu <iamqyh@gmail.com>Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>Discussion:https://postgr.es/m/CAN55FZ0h_YoSqqutxV6DES1RW8ig6wcA8CR9rJk358YRMxZFmw@mail.gmail.com
1 parent5528e8d commit9660906

File tree

2 files changed

+196
-0
lines changed

2 files changed

+196
-0
lines changed

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

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6776,6 +6776,194 @@ EvictRelUnpinnedBuffers(Relation rel, int32 *buffers_evicted,
67766776
}
67776777
}
67786778

6779+
/*
6780+
* Helper function to mark unpinned buffer dirty whose buffer header lock is
6781+
* already acquired.
6782+
*/
6783+
staticbool
6784+
MarkDirtyUnpinnedBufferInternal(Bufferbuf,BufferDesc*desc,
6785+
bool*buffer_already_dirty)
6786+
{
6787+
uint32buf_state;
6788+
boolresult= false;
6789+
6790+
*buffer_already_dirty= false;
6791+
6792+
buf_state=pg_atomic_read_u32(&(desc->state));
6793+
Assert(buf_state&BM_LOCKED);
6794+
6795+
if ((buf_state&BM_VALID)==0)
6796+
{
6797+
UnlockBufHdr(desc);
6798+
return false;
6799+
}
6800+
6801+
/* Check that it's not pinned already. */
6802+
if (BUF_STATE_GET_REFCOUNT(buf_state)>0)
6803+
{
6804+
UnlockBufHdr(desc);
6805+
return false;
6806+
}
6807+
6808+
/* Pin the buffer and then release the buffer spinlock */
6809+
PinBuffer_Locked(desc);
6810+
6811+
/* If it was not already dirty, mark it as dirty. */
6812+
if (!(buf_state&BM_DIRTY))
6813+
{
6814+
LWLockAcquire(BufferDescriptorGetContentLock(desc),LW_EXCLUSIVE);
6815+
MarkBufferDirty(buf);
6816+
result= true;
6817+
LWLockRelease(BufferDescriptorGetContentLock(desc));
6818+
}
6819+
else
6820+
*buffer_already_dirty= true;
6821+
6822+
UnpinBuffer(desc);
6823+
6824+
returnresult;
6825+
}
6826+
6827+
/*
6828+
* Try to mark the provided shared buffer as dirty.
6829+
*
6830+
* This function is intended for testing/development use only!
6831+
*
6832+
* Same as EvictUnpinnedBuffer() but with MarkBufferDirty() call inside.
6833+
*
6834+
* The buffer_already_dirty parameter is mandatory and indicate if the buffer
6835+
* could not be dirtied because it is already dirty.
6836+
*
6837+
* Returns true if the buffer has successfully been marked as dirty.
6838+
*/
6839+
bool
6840+
MarkDirtyUnpinnedBuffer(Bufferbuf,bool*buffer_already_dirty)
6841+
{
6842+
BufferDesc*desc;
6843+
boolbuffer_dirtied= false;
6844+
6845+
Assert(!BufferIsLocal(buf));
6846+
6847+
/* Make sure we can pin the buffer. */
6848+
ResourceOwnerEnlarge(CurrentResourceOwner);
6849+
ReservePrivateRefCountEntry();
6850+
6851+
desc=GetBufferDescriptor(buf-1);
6852+
LockBufHdr(desc);
6853+
6854+
buffer_dirtied=MarkDirtyUnpinnedBufferInternal(buf,desc,buffer_already_dirty);
6855+
/* Both can not be true at the same time */
6856+
Assert(!(buffer_dirtied&&*buffer_already_dirty));
6857+
6858+
returnbuffer_dirtied;
6859+
}
6860+
6861+
/*
6862+
* Try to mark all the shared buffers containing provided relation's pages as
6863+
* dirty.
6864+
*
6865+
* This function is intended for testing/development use only! See
6866+
* MarkDirtyUnpinnedBuffer().
6867+
*
6868+
* The buffers_* parameters are mandatory and indicate the total count of
6869+
* buffers that:
6870+
* - buffers_dirtied - were dirtied
6871+
* - buffers_already_dirty - were already dirty
6872+
* - buffers_skipped - could not be dirtied because of a reason different
6873+
* than a buffer being already dirty.
6874+
*/
6875+
void
6876+
MarkDirtyRelUnpinnedBuffers(Relationrel,
6877+
int32*buffers_dirtied,
6878+
int32*buffers_already_dirty,
6879+
int32*buffers_skipped)
6880+
{
6881+
Assert(!RelationUsesLocalBuffers(rel));
6882+
6883+
*buffers_dirtied=0;
6884+
*buffers_already_dirty=0;
6885+
*buffers_skipped=0;
6886+
6887+
for (intbuf=1;buf <=NBuffers;buf++)
6888+
{
6889+
BufferDesc*desc=GetBufferDescriptor(buf-1);
6890+
uint32buf_state=pg_atomic_read_u32(&(desc->state));
6891+
boolbuffer_already_dirty;
6892+
6893+
CHECK_FOR_INTERRUPTS();
6894+
6895+
/* An unlocked precheck should be safe and saves some cycles. */
6896+
if ((buf_state&BM_VALID)==0||
6897+
!BufTagMatchesRelFileLocator(&desc->tag,&rel->rd_locator))
6898+
continue;
6899+
6900+
/* Make sure we can pin the buffer. */
6901+
ResourceOwnerEnlarge(CurrentResourceOwner);
6902+
ReservePrivateRefCountEntry();
6903+
6904+
buf_state=LockBufHdr(desc);
6905+
6906+
/* recheck, could have changed without the lock */
6907+
if ((buf_state&BM_VALID)==0||
6908+
!BufTagMatchesRelFileLocator(&desc->tag,&rel->rd_locator))
6909+
{
6910+
UnlockBufHdr(desc);
6911+
continue;
6912+
}
6913+
6914+
if (MarkDirtyUnpinnedBufferInternal(buf,desc,&buffer_already_dirty))
6915+
(*buffers_dirtied)++;
6916+
elseif (buffer_already_dirty)
6917+
(*buffers_already_dirty)++;
6918+
else
6919+
(*buffers_skipped)++;
6920+
}
6921+
}
6922+
6923+
/*
6924+
* Try to mark all the shared buffers as dirty.
6925+
*
6926+
* This function is intended for testing/development use only! See
6927+
* MarkDirtyUnpinnedBuffer().
6928+
*
6929+
* See MarkDirtyRelUnpinnedBuffers() above for details about the buffers_*
6930+
* parameters.
6931+
*/
6932+
void
6933+
MarkDirtyAllUnpinnedBuffers(int32*buffers_dirtied,
6934+
int32*buffers_already_dirty,
6935+
int32*buffers_skipped)
6936+
{
6937+
*buffers_dirtied=0;
6938+
*buffers_already_dirty=0;
6939+
*buffers_skipped=0;
6940+
6941+
for (intbuf=1;buf <=NBuffers;buf++)
6942+
{
6943+
BufferDesc*desc=GetBufferDescriptor(buf-1);
6944+
uint32buf_state;
6945+
boolbuffer_already_dirty;
6946+
6947+
CHECK_FOR_INTERRUPTS();
6948+
6949+
buf_state=pg_atomic_read_u32(&desc->state);
6950+
if (!(buf_state&BM_VALID))
6951+
continue;
6952+
6953+
ResourceOwnerEnlarge(CurrentResourceOwner);
6954+
ReservePrivateRefCountEntry();
6955+
6956+
LockBufHdr(desc);
6957+
6958+
if (MarkDirtyUnpinnedBufferInternal(buf,desc,&buffer_already_dirty))
6959+
(*buffers_dirtied)++;
6960+
elseif (buffer_already_dirty)
6961+
(*buffers_already_dirty)++;
6962+
else
6963+
(*buffers_skipped)++;
6964+
}
6965+
}
6966+
67796967
/*
67806968
* Generic implementation of the AIO handle staging callback for readv/writev
67816969
* on local/shared buffers.

‎src/include/storage/bufmgr.h‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,14 @@ extern void EvictRelUnpinnedBuffers(Relation rel,
323323
int32*buffers_evicted,
324324
int32*buffers_flushed,
325325
int32*buffers_skipped);
326+
externboolMarkDirtyUnpinnedBuffer(Bufferbuf,bool*buffer_already_dirty);
327+
externvoidMarkDirtyRelUnpinnedBuffers(Relationrel,
328+
int32*buffers_dirtied,
329+
int32*buffers_already_dirty,
330+
int32*buffers_skipped);
331+
externvoidMarkDirtyAllUnpinnedBuffers(int32*buffers_dirtied,
332+
int32*buffers_already_dirty,
333+
int32*buffers_skipped);
326334

327335
/* in buf_init.c */
328336
externvoidBufferManagerShmemInit(void);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp