We have a wait-pin-to-1 mechanism in LockBufferForCleanup() like this: 1: bufHdr->wait_backend_pid = MyProcPid; 2: bufHdr->flags |= BM_PIN_COUNT_WAITER; 3: PinCountWaitBuf = bufHdr; 4: UnlockBufHdr_NoHoldoff(bufHdr); 5: LockBuffer(buffer, BUFFER_LOCK_UNLOCK); 6: /* Wait to be signaled by UnpinBuffer() */ 7: ProcWaitForSignal();
Say if the waiter encounters an error on line 5 or gets a cancel signal on line 6, it will abort current transaction and call UnlockBuffers() to cancel the wait. However, a possible execution sequence involving another process doing UnpinBuffer() may look like this: unpinner: lockHdr(); read and reset flag; unlockHdr(); waiter: lockHdr(); reset flag; unlockHdr(); ProcCancelWaitForSignal(); unpinner: ProcSendSignal(); After this, the proc->sem will be bumped to 1 unexpectedly ... Since this problem is rare, a possible fix is to put a critical section around line 1 to 7 and remove UnlockBuffers() accordingly. Regards, Qingqing ---------------------------(end of broadcast)--------------------------- TIP 4: Have you searched our list archives? http://archives.postgresql.org