diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 8b3983988a484eb8774e10bbd9a35837e3cb2429..591906bb6cdde346268ee6f6b50ab985d7073b73 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 @@ -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 62f2a80adc8766fc07d4fbe1230b8a1c7c340b2b..229385862c5b5a9768089bbde4ed688f64570d1b 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 (*preCacheNodesCountPtr == 0 || secondring) + { + elog(ERROR, "no unpinned buffers available"); + } + secondring = true; + trycounter = NBuffers; } UnlockBufHdr(buf, local_buf_state); }