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 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<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);
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<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()) {
metaData.setFreePages(0);
} else {

View File

@ -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);