From 5d3a3fcca7fbc04e60a146e42fb1f65b94e4ea7b Mon Sep 17 00:00:00 2001 From: gtully Date: Wed, 17 Oct 2018 12:32:04 +0100 Subject: [PATCH] AMQ-6590 - rework fix to take the recovery hit on clean shutdown rather than on restart, trade off availability for short term disk usage --- .../store/kahadb/disk/page/PageFile.java | 31 +++++++++++-------- .../store/kahadb/disk/page/PageFileTest.java | 4 +-- 2 files changed, 20 insertions(+), 15 deletions(-) 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 5699c450a2..b426a72311 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 @@ -145,6 +145,8 @@ public class PageFile { private boolean useLFRUEviction = false; private float LFUEvictionFactor = 0.2f; + private boolean needsFreePageRecovery = false; + /** * Use to keep track of updated pages which have not yet been committed. */ @@ -401,8 +403,6 @@ public class PageFile { recoveryFile = new RecoverableRandomAccessFile(getRecoveryFile(), "rw"); } - boolean needsFreePageRecovery = false; - if (metaData.isCleanShutdown()) { nextTxid.set(metaData.getLastTxId() + 1); if (metaData.getFreePages() > 0) { @@ -419,17 +419,6 @@ public class PageFile { } nextFreePageId.set((writeFile.length() - PAGE_FILE_HEADER_SIZE) / pageSize); - if (needsFreePageRecovery) { - // Scan all to find the free pages after nextFreePageId is set - freeList = new SequenceSet(); - for (Iterator i = tx().iterator(true); i.hasNext(); ) { - Page page = i.next(); - if (page.getType() == Page.PAGE_FREE_TYPE) { - freeList.add(page.getPageId()); - } - } - } - metaData.setCleanShutdown(false); storeMetaData(); getFreeFile().delete(); @@ -456,6 +445,22 @@ public class PageFile { throw new InterruptedIOException(); } + if (needsFreePageRecovery) { + LOG.info(toString() + ". Recovering pageFile free list due to prior unclean shutdown.."); + freeList = new SequenceSet(); + loaded.set(true); + try { + for (Iterator i = new Transaction(this).iterator(true); i.hasNext(); ) { + Page page = i.next(); + if (page.getType() == Page.PAGE_FREE_TYPE) { + freeList.add(page.getPageId()); + } + } + } finally { + loaded.set(false); + } + } + if (freeList.isEmpty()) { metaData.setFreePages(0); } else { 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 c5a84e92bf..1bdbe6f379 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 @@ -219,10 +219,10 @@ public class PageFileTest extends TestCase { PageFile pf2 = new PageFile(new File("target/test-data"), getName()); pf2.setEnableRecoveryFile(false); pf2.load(); - + pf2.unload(); + pf2.load(); long freePages = pf2.getFreePageCount(); pf.unload(); - pf2.unload(); //Make sure that all 10 pages are still tracked assertEquals(10, freePages);