You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cs...@apache.org on 2017/02/02 12:06:37 UTC
activemq git commit: https://issues.apache.org/jira/browse/AMQ-6590
Repository: activemq
Updated Branches:
refs/heads/master 9b9e3d367 -> 38d85be47
https://issues.apache.org/jira/browse/AMQ-6590
Fix KahaDB index free page recovery on unclean shutdown so that existing
free pages will be tracked and not lost.
Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/38d85be4
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/38d85be4
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/38d85be4
Branch: refs/heads/master
Commit: 38d85be476a06fe9a1f60b4f38232d64a6d0398a
Parents: 9b9e3d3
Author: Christopher L. Shannon (cshannon) <ch...@gmail.com>
Authored: Thu Feb 2 07:05:28 2017 -0500
Committer: Christopher L. Shannon (cshannon) <ch...@gmail.com>
Committed: Thu Feb 2 07:06:11 2017 -0500
----------------------------------------------------------------------
.../store/kahadb/disk/page/PageFile.java | 18 +++++++-----
.../store/kahadb/disk/page/PageFileTest.java | 30 ++++++++++++++++++++
2 files changed, 41 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/activemq/blob/38d85be4/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/page/PageFile.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/page/PageFile.java b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/page/PageFile.java
index 51b217d..f56539b 100644
--- a/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/page/PageFile.java
+++ b/activemq-kahadb-store/src/main/java/org/apache/activemq/store/kahadb/disk/page/PageFile.java
@@ -401,6 +401,8 @@ public class PageFile {
recoveryFile = new RecoverableRandomAccessFile(getRecoveryFile(), "rw");
}
+ boolean needsFreePageRecovery = false;
+
if (metaData.isCleanShutdown()) {
nextTxid.set(metaData.getLastTxId() + 1);
if (metaData.getFreePages() > 0) {
@@ -409,8 +411,16 @@ public class PageFile {
} else {
LOG.debug(toString() + ", Recovering page file...");
nextTxid.set(redoRecoveryUpdates());
+ needsFreePageRecovery = true;
+ }
+
+ if (writeFile.length() < PAGE_FILE_HEADER_SIZE) {
+ writeFile.setLength(PAGE_FILE_HEADER_SIZE);
+ }
+ nextFreePageId.set((writeFile.length() - PAGE_FILE_HEADER_SIZE) / pageSize);
- // Scan all to find the free pages.
+ if (needsFreePageRecovery) {
+ // Scan all to find the free pages after nextFreePageId is set
freeList = new SequenceSet();
for (Iterator<Page> i = tx().iterator(true); i.hasNext(); ) {
Page page = i.next();
@@ -423,13 +433,7 @@ public class PageFile {
metaData.setCleanShutdown(false);
storeMetaData();
getFreeFile().delete();
-
- if (writeFile.length() < PAGE_FILE_HEADER_SIZE) {
- writeFile.setLength(PAGE_FILE_HEADER_SIZE);
- }
- nextFreePageId.set((writeFile.length() - PAGE_FILE_HEADER_SIZE) / pageSize);
startWriter();
-
} else {
throw new IllegalStateException("Cannot load the page file when it is already loaded.");
}
http://git-wip-us.apache.org/repos/asf/activemq/blob/38d85be4/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/page/PageFileTest.java
----------------------------------------------------------------------
diff --git a/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/page/PageFileTest.java b/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/page/PageFileTest.java
index 91f6c40..a39f30c 100644
--- a/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/page/PageFileTest.java
+++ b/activemq-kahadb-store/src/test/java/org/apache/activemq/store/kahadb/disk/page/PageFileTest.java
@@ -22,9 +22,11 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.lang.reflect.Field;
import java.util.HashSet;
import org.apache.activemq.store.kahadb.disk.util.StringMarshaller;
+import org.apache.activemq.util.RecoverableRandomAccessFile;
import junit.framework.TestCase;
@@ -199,4 +201,32 @@ public class PageFileTest extends TestCase {
}
assertEquals(expected, actual);
}
+
+ //Test for AMQ-6590
+ public void testFreePageRecoveryUncleanShutdown() throws Exception {
+
+ PageFile pf = new PageFile(new File("target/test-data"), getName());
+ pf.delete();
+ pf.setEnableRecoveryFile(false);
+ pf.load();
+
+ //Allocate 10 free pages
+ Transaction tx = pf.tx();
+ tx.allocate(10);
+ tx.commit();
+ pf.flush();
+
+ //Load a second instance on the same directory fo the page file which
+ //simulates an unclean shutdown from the previous run
+ PageFile pf2 = new PageFile(new File("target/test-data"), getName());
+ pf2.setEnableRecoveryFile(false);
+ pf2.load();
+
+ long freePages = pf2.getFreePageCount();
+ pf.unload();
+ pf2.unload();
+
+ //Make sure that all 10 pages are still tracked
+ assertEquals(10, freePages);
+ }
}