activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cshan...@apache.org
Subject activemq git commit: https://issues.apache.org/jira/browse/AMQ-6590
Date Thu, 02 Feb 2017 12:06:37 GMT
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) <christopher.l.shannon@gmail.com>
Authored: Thu Feb 2 07:05:28 2017 -0500
Committer: Christopher L. Shannon (cshannon) <christopher.l.shannon@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);
+    }
 }


Mime
View raw message