From: Heikki Linnakangas Date: Wed, 27 Mar 2013 19:51:27 +0000 (+0200) Subject: Fix buffer pin leak in heap update redo routine. X-Git-Tag: REL9_0_13~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=336e493934bd912128d738404e104be108943fba;p=postgresql Fix buffer pin leak in heap update redo routine. In a heap update, if the old and new tuple were on different pages, and the new page no longer existed (because it was subsequently truncated away by vacuum), heap_xlog_update forgot to release the pin on the old buffer. This bug was introduced by the "Fix multiple problems in WAL replay" patch, commit 3bbf668de9f1bc172371681e80a4e769b6d014c8 (on master branch). With full_page_writes=off, this triggered an "incorrect local pin count" error later in replay, if the old page was vacuumed. This fixes bug #7969, reported by Yunong Xiao. Backpatch to 9.0, like the commit that introduced this bug. --- diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c index 4f4b5712a4..766f77acc1 100644 --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -4670,7 +4670,11 @@ newt:; ItemPointerGetBlockNumber(&(xlrec->newtid)), false); if (!BufferIsValid(nbuffer)) + { + if (BufferIsValid(obuffer)) + UnlockReleaseBuffer(obuffer); return; + } page = (Page) BufferGetPage(nbuffer); if (XLByteLE(lsn, PageGetLSN(page))) /* changes are applied */