You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by mi...@apache.org on 2006/04/13 18:38:39 UTC

svn commit: r393855 - in /db/derby/code/branches/10.1/java: engine/org/apache/derby/impl/store/raw/data/ testing/org/apache/derbyTesting/functionTests/master/ testing/org/apache/derbyTesting/functionTests/suites/ testing/org/apache/derbyTesting/functio...

Author: mikem
Date: Thu Apr 13 09:38:34 2006
New Revision: 393855

URL: http://svn.apache.org/viewcvs?rev=393855&view=rev
Log:
DERBY-1189

backporting fix (svn 392194) from trunk to 10.1 branch:

inplace compress could self deadlock on a latch/latch conflict.  Changed
the insert page find code for defragment to never return a page which is
higher than the source page of the row.  Previously the upper level code
made this decision, but that was too late.  As part of the change also
optimized the "unfilled" search to be biased towards those pages near
the front of the container.  Checkin includes simple sql script which
reproduced the deadlock prior to the fix.


Added:
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out
      - copied unchanged from r392194, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql
      - copied unchanged from r392194, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties
      - copied unchanged from r392194, db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties
Modified:
    db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
    db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant

Modified: db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java?rev=393855&r1=393854&r2=393855&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java (original)
+++ db/derby/code/branches/10.1/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java Thu Apr 13 09:38:34 2006
@@ -2689,13 +2689,98 @@
 		return p;
 	}
 
+    /**
+     * Get candidate page to move a row for compressing the table.
+     * <p>
+     * The caller is moving rows from the end of the table toward the beginning,
+     * with the goal of freeing up a block of empty pages at the end of the
+     * container which can be returned to the OS.
+     * <p>
+     * On entry pageno will be latched by the caller.  Only return pages with
+     * numbers below pageno.  Attempting to return pageno will result in a
+     * latch/latch deadlock on the same thread.
+     *
+	 * @exception  StandardException  Standard exception policy.
+     **/
 	protected BasePage getPageForCompress(
     BaseContainerHandle handle,
     int                 flag,
     long                pageno)
 		 throws StandardException
 	{
-        return(getPageForInsert(handle, flag));
+		BasePage p = null;
+		boolean getLastInserted = 
+            (flag & ContainerHandle.GET_PAGE_UNFILLED) == 0;
+
+		if (getLastInserted)
+		{
+			// There is nothing protecting lastInsertePage from being changed
+			// by another thread.  Make a local copy.
+			long localLastInsertedPage = getLastInsertedPage();
+
+            if ((localLastInsertedPage < pageno) &&
+                (localLastInsertedPage != ContainerHandle.INVALID_PAGE_NUMBER))
+            {
+                // First try getting last inserted page.
+
+                p = getInsertablePage(
+                        handle, 
+                        localLastInsertedPage,
+                        true, /* wait */
+                        false /* no overflow page */);
+
+                // if localLastInsertedPage is not an insertable page, 
+                // don't waste time getting it again.
+                if (p == null)
+                {
+                    // There is a slight possibility that lastUnfilledPage and
+                    // lastInsertedPage will change between the if and the
+                    // assignment.  The worse that will happen is we lose the
+                    // optimization.  Don't want to slow down allocation by 
+                    // adding more synchronization.
+
+                    if (localLastInsertedPage == getLastUnfilledPage())
+                        setLastUnfilledPage(
+                            ContainerHandle.INVALID_PAGE_NUMBER);
+
+                    if (localLastInsertedPage == getLastInsertedPage())
+                        setLastInsertedPage(
+                            ContainerHandle.INVALID_PAGE_NUMBER);
+                }
+            }
+		}
+		else					
+		{
+            // get a relatively unfilled page that is not the last Inserted page
+
+			long localLastUnfilledPage = getLastUnfilledPage();
+
+			if (localLastUnfilledPage == ContainerHandle.INVALID_PAGE_NUMBER ||
+                localLastUnfilledPage >= pageno ||
+				localLastUnfilledPage == getLastInsertedPage())
+            {
+                // get an unfilled page, searching from beginning of container.
+				localLastUnfilledPage = 
+                    getUnfilledPageNumber(handle, 0);
+            }
+
+			if ((localLastUnfilledPage != 
+                    ContainerHandle.INVALID_PAGE_NUMBER) &&
+                (localLastUnfilledPage < pageno))
+			{
+				p = getInsertablePage(
+                        handle, localLastUnfilledPage, true, false);
+			}
+
+			// return this page for insert
+			if (p != null)
+			{
+				setLastUnfilledPage(localLastUnfilledPage);
+				setLastInsertedPage(localLastUnfilledPage);
+			}
+		}
+
+		return p;
     }
 
 	/**

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall?rev=393855&r1=393854&r2=393855&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall Thu Apr 13 09:38:34 2006
@@ -1,4 +1,5 @@
 storetests/st_schema.sql
+storetests/st_derby1189.sql
 storetests/st_derby715.java
 storetests/st_1.sql
 storetests/st_b5772.sql

Modified: db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant
URL: http://svn.apache.org/viewcvs/db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant?rev=393855&r1=393854&r2=393855&view=diff
==============================================================================
--- db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant (original)
+++ db/derby/code/branches/10.1/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant Thu Apr 13 09:38:34 2006
@@ -11,3 +11,4 @@
 derby94_derby.properties
 onlineCompressTable.sql
 derby94_derby.properties
+st_derby1189.sql