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/07 08:11:16 UTC

svn commit: r392194 - in /db/derby/code/trunk/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/functionTests/t...

Author: mikem
Date: Thu Apr  6 23:11:13 2006
New Revision: 392194

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

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/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/copyfiles.ant

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java?rev=392194&r1=392193&r2=392194&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/data/FileContainer.java Thu Apr  6 23:11:13 2006
@@ -2790,13 +2790,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;
     }
 
 	/**

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out?rev=392194&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/st_derby1189.out Thu Apr  6 23:11:13 2006
@@ -0,0 +1,44 @@
+ij> drop table t1;
+ERROR 42Y55: 'DROP TABLE' cannot be performed on 'T1' because it does not exist.
+ij> create table t1 (i integer primary key, j integer, c char(200));
+0 rows inserted/updated/deleted
+ij> insert into t1 values (1, 1, 'a');
+1 row inserted/updated/deleted
+ij> insert into t1 (select t1.i + 2,    t1.j + 2,    t1.c from t1);
+1 row inserted/updated/deleted
+ij> insert into t1 (select t1.i + 4,    t1.j + 4,    t1.c from t1);
+2 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 8,    t1.j + 8,    t1.c from t1);
+4 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 16,   t1.j + 16,   t1.c from t1);
+8 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 32,   t1.j + 32,   t1.c from t1);
+16 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 64,   t1.j + 64,   t1.c from t1);
+32 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 128,  t1.j + 128,  t1.c from t1);
+64 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 256,  t1.j + 256,  t1.c from t1);
+128 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 512,  t1.j + 512,  t1.c from t1);
+256 rows inserted/updated/deleted
+ij> insert into t1 (select t1.i + 1024, t1.j + 1024, t1.c from t1);
+512 rows inserted/updated/deleted
+ij> delete from t1 where j=1;
+1 row inserted/updated/deleted
+ij> CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+0 rows inserted/updated/deleted
+ij> delete from t1 where j=2;
+0 rows inserted/updated/deleted
+ij> CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+0 rows inserted/updated/deleted
+ij> delete from t1 where i > 1024;
+512 rows inserted/updated/deleted
+ij> CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+0 rows inserted/updated/deleted
+ij> delete from t1 where i < 512;
+255 rows inserted/updated/deleted
+ij> -- prior to the fix the following compress would result in a deadlock
+CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+0 rows inserted/updated/deleted
+ij> 

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall?rev=392194&r1=392193&r2=392194&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/storetests.runall Thu Apr  6 23:11:13 2006
@@ -1,4 +1,5 @@
 storetests/st_schema.sql
+storetests/st_derby1189.sql
 storetests/st_reclaim_longcol.java
 storetests/st_derby715.java
 storetests/st_1.sql

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

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql?rev=392194&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189.sql Thu Apr  6 23:11:13 2006
@@ -0,0 +1,30 @@
+drop table t1;
+create table t1 (i integer primary key, j integer, c char(200));
+insert into t1 values (1, 1, 'a');
+insert into t1 (select t1.i + 2,    t1.j + 2,    t1.c from t1);
+insert into t1 (select t1.i + 4,    t1.j + 4,    t1.c from t1);
+insert into t1 (select t1.i + 8,    t1.j + 8,    t1.c from t1);
+insert into t1 (select t1.i + 16,   t1.j + 16,   t1.c from t1);
+insert into t1 (select t1.i + 32,   t1.j + 32,   t1.c from t1);
+insert into t1 (select t1.i + 64,   t1.j + 64,   t1.c from t1);
+insert into t1 (select t1.i + 128,  t1.j + 128,  t1.c from t1);
+insert into t1 (select t1.i + 256,  t1.j + 256,  t1.c from t1);
+insert into t1 (select t1.i + 512,  t1.j + 512,  t1.c from t1);
+insert into t1 (select t1.i + 1024, t1.j + 1024, t1.c from t1);
+
+delete from t1 where j=1;
+
+CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+
+delete from t1 where j=2;
+
+CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+
+delete from t1 where i > 1024;
+
+CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);
+
+delete from t1 where i < 512;
+
+-- prior to the fix the following compress would result in a deadlock
+CALL SYSCS_UTIL.SYSCS_INPLACE_COMPRESS_TABLE('APP', 'T1', 1, 1, 1);

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties
URL: http://svn.apache.org/viewcvs/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties?rev=392194&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/storetests/st_derby1189_app.properties Thu Apr  6 23:11:13 2006
@@ -0,0 +1,2 @@
+usedefaults=true
+