*** a/src/backend/storage/buffer/bufmgr.c --- b/src/backend/storage/buffer/bufmgr.c *************** *** 1390,1395 **** BgBufferSync(void) --- 1390,1396 ---- /* Variables for final smoothed_density update */ long new_strategy_delta; uint32 new_recent_alloc; + volatile BufferDesc *bufHdr; /* * Find out where the freelist clock sweep currently is, and how many *************** *** 1575,1580 **** BgBufferSync(void) --- 1576,1582 ---- { int buffer_state = SyncOneBuffer(next_to_clean, true); + bufHdr = &BufferDescriptors[next_to_clean]; if (++next_to_clean >= NBuffers) { next_to_clean = 0; *************** *** 1592,1598 **** BgBufferSync(void) --- 1594,1603 ---- } } else if (buffer_state & BUF_REUSABLE) + { reusable_buffers++; + StrategyMoveBufferToFreeListEnd (bufHdr); + } } BgWriterStats.m_buf_written_clean += num_written; *** a/src/backend/storage/buffer/freelist.c --- b/src/backend/storage/buffer/freelist.c *************** *** 259,264 **** StrategyFreeBuffer(volatile BufferDesc *buf) --- 259,296 ---- } /* + * StrategyMoveBufferToFreeListEnd: put a buffer on the end of freelist + */ + void + StrategyMoveBufferToFreeListEnd(volatile BufferDesc *buf) + { + LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + /* + * It is possible that we are told to put something in the freelist that + * is already in it; don't screw up the list if so. + */ + if (buf->freeNext == FREENEXT_NOT_IN_LIST) + { + /* + * put the buffer on end of list and if list is empty then + * assign first and last freebuffer with this buffer id. + */ + buf->freeNext = FREENEXT_END_OF_LIST; + if (StrategyControl->firstFreeBuffer < 0) + { + StrategyControl->firstFreeBuffer = buf->buf_id; + StrategyControl->lastFreeBuffer = buf->buf_id; + LWLockRelease(BufFreelistLock); + return; + } + BufferDescriptors[StrategyControl->lastFreeBuffer].freeNext = buf->buf_id; + StrategyControl->lastFreeBuffer = buf->buf_id; + } + LWLockRelease(BufFreelistLock); + } + + + /* * StrategySyncStart -- tell BufferSync where to start syncing * * The result is the buffer index of the best buffer to sync first. *** a/src/include/storage/buf_internals.h --- b/src/include/storage/buf_internals.h *************** *** 185,190 **** extern BufferDesc *LocalBufferDescriptors; --- 185,191 ---- extern volatile BufferDesc *StrategyGetBuffer(BufferAccessStrategy strategy, bool *lock_held); extern void StrategyFreeBuffer(volatile BufferDesc *buf); + extern void StrategyMoveBufferToFreeListEnd(volatile BufferDesc *buf); extern bool StrategyRejectBuffer(BufferAccessStrategy strategy, volatile BufferDesc *buf);