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
+