summaryrefslogtreecommitdiff
path: root/src/backend/access/heap
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-05-07 21:32:53 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-05-07 21:32:53 +0000
commitd6e30b0ba0028d56b555f91f524aabb65d1a8443 (patch)
tree2b58de1c06327def472a6772084649f28add35ce /src/backend/access/heap
parentaba1f93e453cbe8efe4ef00204b5db329f803c68 (diff)
Repair very-low-probability race condition between relation extension
and VACUUM: in the interval between adding a new page to the relation and formatting it, it was possible for VACUUM to come along and decide it should format the page too. Though not harmful in itself, this would cause data loss if a third transaction were able to insert tuples into the vacuumed page before the original extender got control back.
Diffstat (limited to 'src/backend/access/heap')
-rw-r--r--src/backend/access/heap/hio.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index 27af323ed11..46c2fd31e04 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.54 2004/12/31 21:59:16 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/access/heap/hio.c,v 1.54.4.1 2005/05/07 21:32:52 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -247,13 +247,6 @@ RelationGetBufferForTuple(Relation relation, Size len,
buffer = ReadBuffer(relation, P_NEW);
/*
- * Release the file-extension lock; it's now OK for someone else to
- * extend the relation some more.
- */
- if (needLock)
- UnlockPage(relation, 0, ExclusiveLock);
-
- /*
* We can be certain that locking the otherBuffer first is OK, since
* it must have a lower page number.
*/
@@ -261,9 +254,22 @@ RelationGetBufferForTuple(Relation relation, Size len,
LockBuffer(otherBuffer, BUFFER_LOCK_EXCLUSIVE);
/*
- * We need to initialize the empty new page.
+ * Now acquire lock on the new page.
*/
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
+
+ /*
+ * Release the file-extension lock; it's now OK for someone else to
+ * extend the relation some more. Note that we cannot release this
+ * lock before we have buffer lock on the new page, or we risk a
+ * race condition against vacuumlazy.c --- see comments therein.
+ */
+ if (needLock)
+ UnlockPage(relation, 0, ExclusiveLock);
+
+ /*
+ * We need to initialize the empty new page.
+ */
pageHeader = (Page) BufferGetPage(buffer);
Assert(PageIsNew((PageHeader) pageHeader));
PageInit(pageHeader, BufferGetPageSize(buffer), 0);