aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-03-27 21:51:27 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-03-27 22:00:01 +0200
commit3cfb572dde2095df1bfc6665862dcf8ee0a95b99 (patch)
treee1ad318c90567c8af68d4c289aeb2d53d49f8d8c
parent7a5a59d378e052618d6feae64d1d2b4f2ad6f9bc (diff)
downloadpostgresql-3cfb572dde2095df1bfc6665862dcf8ee0a95b99.tar.gz
postgresql-3cfb572dde2095df1bfc6665862dcf8ee0a95b99.zip
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.
-rw-r--r--src/backend/access/heap/heapam.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index fe563188876..9498cbb8a51 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -6824,7 +6824,11 @@ newt:;
ItemPointerGetBlockNumber(&(xlrec->newtid)),
false);
if (!BufferIsValid(nbuffer))
+ {
+ if (BufferIsValid(obuffer))
+ UnlockReleaseBuffer(obuffer);
return;
+ }
page = (Page) BufferGetPage(nbuffer);
if (lsn <= PageGetLSN(page)) /* changes are applied */