Possible race in UnlockBuffers() and UnpinBuffer()
От | Qingqing Zhou |
---|---|
Тема | Possible race in UnlockBuffers() and UnpinBuffer() |
Дата | |
Msg-id | e1l18q$2nba$1@news.hub.org обсуждение исходный текст |
Ответы |
Re: Possible race in UnlockBuffers() and UnpinBuffer()
|
Список | pgsql-hackers |
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 byUnpinBuffer() */ 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
В списке pgsql-hackers по дате отправления: