Convert Assert checking for empty page into a regular test and elog.
authorTom Lane <[email protected]>
Fri, 6 Jan 2006 00:16:09 +0000 (00:16 +0000)
committerTom Lane <[email protected]>
Fri, 6 Jan 2006 00:16:09 +0000 (00:16 +0000)
The consequences of overwriting a non-empty page are bad enough that
we should not omit this test in production builds.

src/backend/access/heap/hio.c

index 5a950ddf375f6891318dd8125a523b2a9d13d1f2..2546e72c62cbca0e25c22db9f39ce6f622fcf56e 100644 (file)
@@ -246,13 +246,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,11 +254,31 @@ 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.  Double-check that it really
+        * is empty (this should never happen, but if it does we don't want to
+        * risk wiping out valid data).
+        */
        pageHeader = (Page) BufferGetPage(buffer);
-       Assert(PageIsNew((PageHeader) pageHeader));
+
+       if (!PageIsNew((PageHeader) pageHeader))
+               elog(ERROR, "page %u of relation \"%s\" should be empty but is not",
+                        BufferGetBlockNumber(buffer),
+                        RelationGetRelationName(relation));
+
        PageInit(pageHeader, BufferGetPageSize(buffer), 0);
 
        if (len > PageGetFreeSpace(pageHeader))