AMQ-6590 - rework fix to take the recovery hit on clean shutdown rather than on restart, trade off availability for short term disk usage

This commit is contained in:
gtully 2018-10-17 12:32:04 +01:00
parent 4dee173962
commit 5d3a3fcca7
2 changed files with 20 additions and 15 deletions

View File

@ -145,6 +145,8 @@ public class PageFile {
private boolean useLFRUEviction = false; private boolean useLFRUEviction = false;
private float LFUEvictionFactor = 0.2f; private float LFUEvictionFactor = 0.2f;
private boolean needsFreePageRecovery = false;
/** /**
* Use to keep track of updated pages which have not yet been committed. * 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"); recoveryFile = new RecoverableRandomAccessFile(getRecoveryFile(), "rw");
} }
boolean needsFreePageRecovery = false;
if (metaData.isCleanShutdown()) { if (metaData.isCleanShutdown()) {
nextTxid.set(metaData.getLastTxId() + 1); nextTxid.set(metaData.getLastTxId() + 1);
if (metaData.getFreePages() > 0) { if (metaData.getFreePages() > 0) {
@ -419,17 +419,6 @@ public class PageFile {
} }
nextFreePageId.set((writeFile.length() - PAGE_FILE_HEADER_SIZE) / pageSize); 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<Page> i = tx().iterator(true); i.hasNext(); ) {
Page page = i.next();
if (page.getType() == Page.PAGE_FREE_TYPE) {
freeList.add(page.getPageId());
}
}
}
metaData.setCleanShutdown(false); metaData.setCleanShutdown(false);
storeMetaData(); storeMetaData();
getFreeFile().delete(); getFreeFile().delete();
@ -456,6 +445,22 @@ public class PageFile {
throw new InterruptedIOException(); 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<Page> 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()) { if (freeList.isEmpty()) {
metaData.setFreePages(0); metaData.setFreePages(0);
} else { } else {

View File

@ -219,10 +219,10 @@ public class PageFileTest extends TestCase {
PageFile pf2 = new PageFile(new File("target/test-data"), getName()); PageFile pf2 = new PageFile(new File("target/test-data"), getName());
pf2.setEnableRecoveryFile(false); pf2.setEnableRecoveryFile(false);
pf2.load(); pf2.load();
pf2.unload();
pf2.load();
long freePages = pf2.getFreePageCount(); long freePages = pf2.getFreePageCount();
pf.unload(); pf.unload();
pf2.unload();
//Make sure that all 10 pages are still tracked //Make sure that all 10 pages are still tracked
assertEquals(10, freePages); assertEquals(10, freePages);