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 2011/06/24 00:53:53 UTC
svn commit: r1139109 - in
/db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access:
btree/BTreeController.java heap/HeapPostCommit.java
Author: mikem
Date: Thu Jun 23 22:53:52 2011
New Revision: 1139109
URL: http://svn.apache.org/viewvc?rev=1139109&view=rev
Log:
DERBY-5284 A derby crash at exactly right time during a btree split can cause a
corrupt db which can not be booted.
backport fix #1139085 from 10.4 branch to 10.1 branch. clean merge by doing
merge of the 10.4 conflict resolved change.
Fixed a problem during BTREE split. The first phase of btree split sees
if it can reclaim space from committed deleted rows. If it finds any
it purges these rows in a nested internal transaction. It needs to hold
the latch on the page until end of transaction, but did not. This allowed
a very small window of a few instructions where another insert could use
the space on the page and then a system crash could cause the purges to undo
but fail due to the insert.
The fix was to hold the latch and let commit release it.
Modified:
db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/heap/HeapPostCommit.java
Modified: db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java?rev=1139109&r1=1139108&r2=1139109&view=diff
==============================================================================
--- db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java (original)
+++ db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/btree/BTreeController.java Thu Jun 23 22:53:52 2011
@@ -110,7 +110,11 @@ public class BTreeController extends Ope
* it would be a waste to merge the page only to split it again to allow
* the insert of the row causing the split.
*
- * @return true if at least one row was purged.
+ * @return true if at least one row was purged. If true, then the routine
+ * will leave the page latched, and the caller will release
+ * the latch by committing or aborting the transaction. The
+ * latch must be held to end transaction to insure space on
+ * the page remains available for a undo of the purge.
*
* @param open_btree The already open btree to use to get latch on page.
* @param pageno The page number of the leaf to attempt the reclaim on.
@@ -193,8 +197,14 @@ public class BTreeController extends Ope
}
finally
{
- if (controlRow != null)
- controlRow.release();
+ if (controlRow != null)
+ {
+ if (!purged_at_least_one_row)
+ {
+ // Ok to release latch if no purging has happened.
+ controlRow.release();
+ }
+ }
return(purged_at_least_one_row);
}
@@ -307,6 +317,12 @@ public class BTreeController extends Ope
// don't split if we reclaim any rows.
do_split = !reclaim_deleted_rows(split_open_btree, leaf_pageno);
+ // on return if !do_split then the latch on leaf_pageno is held
+ // and will be released by the committing or aborting the
+ // transaction. If a purge has been done, no other action on
+ // the page should be attempted (ie. a split) before committing
+ // the purges.
+
split_open_btree.close();
}
}
@@ -314,6 +330,9 @@ public class BTreeController extends Ope
long new_leaf_pageno = leaf_pageno;
if (do_split)
{
+ // no space was reclaimed from deleted rows, so do split to allow
+ // space for a subsequent insert.
+
split_open_btree = new OpenBTree();
split_open_btree.init(
this.init_open_user_scans,
Modified: db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/heap/HeapPostCommit.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/heap/HeapPostCommit.java?rev=1139109&r1=1139108&r2=1139109&view=diff
==============================================================================
--- db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/heap/HeapPostCommit.java (original)
+++ db/derby/code/branches/10.0/java/engine/org/apache/derby/impl/store/access/heap/HeapPostCommit.java Thu Jun 23 22:53:52 2011
@@ -225,7 +225,10 @@ class HeapPostCommit implements Servicea
{
// If no purge happened on the page and the page is not
// removed, feel free to unlatch it. Otherwise, let
- // transaction commit take care of it.
+ // transaction commit take care of it. The latch must be
+ // held until end transaction in order to insure no other
+ // transaction uses the space freed by the purge, which
+ // would cause a subquent undo of the purge to fail.
if (!purgingDone)
{
page.unlatch();