]> granicus.if.org Git - postgresql/commitdiff
Fix buffer pin leak in heap update redo routine.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 27 Mar 2013 19:51:27 +0000 (21:51 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Wed, 27 Mar 2013 20:05:22 +0000 (22:05 +0200)
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.

src/backend/access/heap/heapam.c

index 595dead3c54a578db31129c7b082df79a46472f2..860fd2039b12c48f695d6d1f9cc9586d80f53ceb 100644 (file)
@@ -5367,7 +5367,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 */