On Mon, Jan 23, 2012 at 3:49 PM, Robert Haas <robertmh...@gmail.com> wrote:
>> The other patches have clearer and specific roles without heuristics >> (mostly), so are at least viable for 9.2, though still requiring >> agreement. > > I think we must also drop removebufmgrfreelist-v1 from consideration, ... I think you misidentify the patch. Earlier you said it that "buffreelistlock-reduction-v1 crapped out" and I already said that the assumption in the code clearly doesn't hold, implying the patch was dropped. The removebufmgrfreelist and its alternate patch is still valid, with applicability to special cases. I've written another patch to assist with testing/assessment of the problems, attached. -- Simon Riggs http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index 3e62448..36b0160 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -17,6 +17,7 @@ #include "storage/buf_internals.h" #include "storage/bufmgr.h" +#include "utils/timestamp.h" /* @@ -41,6 +42,21 @@ typedef struct */ uint32 completePasses; /* Complete cycles of the clock sweep */ uint32 numBufferAllocs; /* Buffers allocated since last reset */ + + /* + * Wait Statistics + */ + long waitBufferAllocSecs; + int waitBufferAllocUSecs; + int waitBufferAlloc; + + long waitBufferFreeSecs; + int waitBufferFreeUSecs; + int waitBufferFree; + + long waitSyncStartSecs; + int waitSyncStartUSecs; + int waitSyncStart; } BufferStrategyControl; /* Pointers to shared state */ @@ -125,7 +141,29 @@ StrategyGetBuffer(BufferAccessStrategy strategy, bool *lock_held) /* Nope, so lock the freelist */ *lock_held = true; - LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + if (!LWLockConditionalAcquire(BufFreelistLock, LW_EXCLUSIVE)) + { + TimestampTz waitStart = GetCurrentTimestamp(); + TimestampTz waitEnd; + long wait_secs; + int wait_usecs; + + LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + + waitEnd = GetCurrentTimestamp(); + + TimestampDifference(waitStart, waitEnd, + &wait_secs, &wait_usecs); + + StrategyControl->waitBufferAllocSecs += wait_secs; + StrategyControl->waitBufferAllocUSecs += wait_usecs; + if (StrategyControl->waitBufferAllocUSecs > 1000000) + { + StrategyControl->waitBufferAllocUSecs -= 1000000; + StrategyControl->waitBufferAllocSecs += 1; + } + StrategyControl->waitBufferAlloc++; + } /* * We count buffer allocation requests so that the bgwriter can estimate @@ -223,7 +261,29 @@ StrategyGetBuffer(BufferAccessStrategy strategy, bool *lock_held) void StrategyFreeBuffer(volatile BufferDesc *buf) { - LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + if (!LWLockConditionalAcquire(BufFreelistLock, LW_EXCLUSIVE)) + { + TimestampTz waitStart = GetCurrentTimestamp(); + TimestampTz waitEnd; + long wait_secs; + int wait_usecs; + + LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + + waitEnd = GetCurrentTimestamp(); + + TimestampDifference(waitStart, waitEnd, + &wait_secs, &wait_usecs); + + StrategyControl->waitBufferFreeSecs += wait_secs; + StrategyControl->waitBufferFreeUSecs += wait_usecs; + if (StrategyControl->waitBufferFreeUSecs > 1000000) + { + StrategyControl->waitBufferFreeUSecs -= 1000000; + StrategyControl->waitBufferFreeSecs += 1; + } + StrategyControl->waitBufferFree++; + } /* * It is possible that we are told to put something in the freelist that @@ -256,7 +316,30 @@ StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc) { int result; - LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + if (!LWLockConditionalAcquire(BufFreelistLock, LW_EXCLUSIVE)) + { + TimestampTz waitStart = GetCurrentTimestamp(); + TimestampTz waitEnd; + long wait_secs; + int wait_usecs; + + LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE); + + waitEnd = GetCurrentTimestamp(); + + TimestampDifference(waitStart, waitEnd, + &wait_secs, &wait_usecs); + + StrategyControl->waitSyncStartSecs += wait_secs; + StrategyControl->waitSyncStartUSecs += wait_usecs; + if (StrategyControl->waitSyncStartUSecs > 1000000) + { + StrategyControl->waitSyncStartUSecs -= 1000000; + StrategyControl->waitSyncStartSecs += 1; + } + StrategyControl->waitSyncStart++; + } + result = StrategyControl->nextVictimBuffer; if (complete_passes) *complete_passes = StrategyControl->completePasses; @@ -265,7 +348,59 @@ StrategySyncStart(uint32 *complete_passes, uint32 *num_buf_alloc) *num_buf_alloc = StrategyControl->numBufferAllocs; StrategyControl->numBufferAllocs = 0; } + else + { + long waitBufferAllocSecs; + int waitBufferAllocUSecs; + int waitBufferAlloc; + + long waitBufferFreeSecs; + int waitBufferFreeUSecs; + int waitBufferFree; + + long waitSyncStartSecs; + int waitSyncStartUSecs; + int waitSyncStart; + + waitBufferAllocSecs = StrategyControl->waitBufferAllocSecs; + waitBufferAllocUSecs = StrategyControl->waitBufferAllocUSecs; + waitBufferAlloc = StrategyControl->waitBufferAlloc; + + waitBufferFreeSecs = StrategyControl->waitBufferFreeSecs; + waitBufferFreeUSecs = StrategyControl->waitBufferFreeUSecs; + waitBufferFree = StrategyControl->waitBufferFree; + + waitSyncStartSecs = StrategyControl->waitSyncStartSecs; + waitSyncStartUSecs = StrategyControl->waitSyncStartUSecs; + waitSyncStart = StrategyControl->waitSyncStart; + + StrategyControl->waitBufferAllocSecs = 0; + StrategyControl->waitBufferAllocUSecs = 0; + StrategyControl->waitBufferAlloc = 0; + + StrategyControl->waitBufferFreeSecs = 0; + StrategyControl->waitBufferFreeUSecs = 0; + StrategyControl->waitBufferFree = 0; + + StrategyControl->waitSyncStartSecs = 0; + StrategyControl->waitSyncStartUSecs = 0; + StrategyControl->waitSyncStart = 0; + + LWLockRelease(BufFreelistLock); + + elog(LOG, "BufFreelistLock stats: " + "BufferAlloc waits %d total wait time=%ld.%03d s; " + "BufferFree waits %d total wait time=%ld.%03d s; " + "SyncStart waits %d total wait time=%ld.%03d s; ", + waitBufferAlloc, waitBufferAllocSecs, waitBufferAllocUSecs, + waitBufferFree, waitBufferFreeSecs, waitBufferFreeUSecs, + waitSyncStart, waitSyncStartSecs, waitSyncStartUSecs); + + return result; + } + LWLockRelease(BufFreelistLock); + return result; }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers