From d95171aa49fc84c5ffcab9340bfcc2c9e8090ff1 Mon Sep 17 00:00:00 2001 From: peitingwei Date: Sat, 7 Oct 2023 15:11:25 +0800 Subject: [PATCH 1/3] support flush precache page --- src/backend/storage/buffer/bufmgr.c | 13 +++++++++++-- src/backend/storage/buffer/freelist.c | 11 +++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 8b398398..1dc28a75 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1528,7 +1528,8 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, * won't prevent hint-bit updates). We will recheck the dirty bit * after re-locking the buffer header. */ - if (oldFlags & BM_DIRTY) + + if ((oldFlags & BM_DIRTY) || (buf->isPreCacheEscape == true && !IsMetaExist(buf->tag.rnode.dbNode,buf->tag.rnode.relNode,buf->tag.forkNum,buf->tag.blockNum))) { /* * We need a share-lock on the buffer contents to write it out @@ -1583,10 +1584,18 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, /* he3db: FlushBuffer to He3DBFlushBuffer*/ // if (push_standby == true) { // master/slave/push standby need to flush dirty page to release space - FlushBuffer(buf, NULL,0); + //FlushBuffer(buf, NULL,0); // } else { // He3DBFlushBuffer(buf, NULL); // } + if ((oldFlags & BM_DIRTY) && buf->isPreCacheEscape == false) + { + FlushBuffer(buf, NULL,0); + } + else + { + FlushBuffer(buf, NULL,1); + } LWLockRelease(BufferDescriptorGetContentLock(buf)); diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index 62f2a80a..88060afc 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -204,6 +204,7 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state) int bgwprocno; int trycounter; uint32 local_buf_state; /* to avoid repeated (de-)referencing */ + bool secondring; /* * If given a strategy object, see whether it can select a buffer. We @@ -314,6 +315,7 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state) /* Nothing on the freelist, so run the "clock sweep" algorithm */ trycounter = NBuffers; + secondring = false; for (;;) { buf = GetBufferDescriptor(ClockSweepTick()); @@ -324,7 +326,7 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state) */ local_buf_state = LockBufHdr(buf); - if (buf->isPreCacheEscape == false && BUF_STATE_GET_REFCOUNT(local_buf_state) == 0) + if (((buf->isPreCacheEscape == false && !secondring) || (buf->isPreCacheEscape == true && secondring)) && BUF_STATE_GET_REFCOUNT(local_buf_state) == 0) { if (BUF_STATE_GET_USAGECOUNT(local_buf_state) != 0) { @@ -351,7 +353,12 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state) * infinite loop. */ UnlockBufHdr(buf, local_buf_state); - elog(ERROR, "no unpinned buffers available"); + if (secondring) + { + elog(ERROR, "no unpinned buffers available"); + } + secondring = true; + trycounter = NBuffers; } UnlockBufHdr(buf, local_buf_state); } -- Gitee From 1c028ae6372729f538d4a6a049dd1bb222df0dd1 Mon Sep 17 00:00:00 2001 From: peitingwei Date: Sat, 7 Oct 2023 16:55:36 +0800 Subject: [PATCH 2/3] set isPreCacheEscape tag while read hot page --- src/backend/storage/buffer/bufmgr.c | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 1dc28a75..591906bb 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -1065,6 +1065,21 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, walRecord.cap = 0; walRecord.buf = NULL; walRecord.count = 0; + + /* for read page precache, not only new extend page*/ + if (*preCacheNodesCountPtr > 0) + { + uint16 preCacheNodei = 0; + while (preCacheNodei < *preCacheNodesCountPtr) + { + if (preCacheNodesPtr[preCacheNodei] == bufHdr->tag.rnode.relNode) + { + bufHdr->isPreCacheEscape=true; + break; + } + preCacheNodei++; + } + } if (isExtend) { @@ -1075,21 +1090,6 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, /* don't set checksum for all-zero page */ - /* for new page precache */ - if (*preCacheNodesCountPtr > 0) - { - uint16 preCacheNodei = 0; - while (preCacheNodei < *preCacheNodesCountPtr) - { - if (preCacheNodesPtr[preCacheNodei] == bufHdr->tag.rnode.relNode) - { - bufHdr->isPreCacheEscape=true; - break; - } - preCacheNodei++; - } - } - /* * NB: we're *not* doing a ScheduleBufferTagForWriteback here; * although we're essentially performing a write. At least on linux -- Gitee From 99d594411def2332d8a79232d88179bb7dfc7a2a Mon Sep 17 00:00:00 2001 From: peitingwei Date: Mon, 16 Oct 2023 19:25:26 +0800 Subject: [PATCH 3/3] Improved memory elimination algorithm --- src/backend/storage/buffer/freelist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index 88060afc..22938586 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -353,7 +353,7 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint32 *buf_state) * infinite loop. */ UnlockBufHdr(buf, local_buf_state); - if (secondring) + if (*preCacheNodesCountPtr == 0 || secondring) { elog(ERROR, "no unpinned buffers available"); } -- Gitee