提交 cd7f1007 authored 作者: Thomas Mueller's avatar Thomas Mueller

When killing the process while the database was writing a checkpoint or while it…

When killing the process while the database was writing a checkpoint or while it was closing, the database could become corrupt. (work in progress)
上级 6dd1a3f4
...@@ -305,10 +305,6 @@ public class PageDataLeaf extends PageData { ...@@ -305,10 +305,6 @@ public class PageDataLeaf extends PageData {
* @return the row * @return the row
*/ */
Row getRowAt(int at) { Row getRowAt(int at) {
int test;
if (rows == null || rows.length == 0) {
System.out.println("stop " + getPos());
}
Row r = rows[at]; Row r = rows[at];
if (r == null) { if (r == null) {
if (firstOverflowPageId == 0) { if (firstOverflowPageId == 0) {
...@@ -376,10 +372,6 @@ if (rows == null || rows.length == 0) { ...@@ -376,10 +372,6 @@ if (rows == null || rows.length == 0) {
return null; return null;
} }
PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1); PageDataNode next = (PageDataNode) index.getPage(parentPageId, -1);
int test;
if (next == null || keys == null) {
System.out.println("stop " + getPos());
}
return next.getNextPage(keys[entryCount - 1]); return next.getNextPage(keys[entryCount - 1]);
} }
......
...@@ -296,15 +296,6 @@ public class PageLog { ...@@ -296,15 +296,6 @@ public class PageLog {
int sessionId = in.readVarInt(); int sessionId = in.readVarInt();
int tableId = in.readVarInt(); int tableId = in.readVarInt();
long key = in.readVarLong(); long key = in.readVarLong();
int todo;
// can not commit immediately
// because the index root may have started to be moved,
// without arriving at the destination yet
// if (stage == RECOVERY_STAGE_UNDO && tableId == -1) {
// // immediately commit,
// // because the pages may be re-used
// setLastCommitForSession(sessionId, logId, pos);
// }
if (stage == RECOVERY_STAGE_REDO) { if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) { if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) { if (trace.isDebugEnabled()) {
......
...@@ -12,7 +12,6 @@ import java.util.ArrayList; ...@@ -12,7 +12,6 @@ import java.util.ArrayList;
import java.util.BitSet; import java.util.BitSet;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator;
import java.util.zip.CRC32; import java.util.zip.CRC32;
import org.h2.command.ddl.CreateTableData; import org.h2.command.ddl.CreateTableData;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
...@@ -35,14 +34,13 @@ import org.h2.index.PageDelegateIndex; ...@@ -35,14 +34,13 @@ import org.h2.index.PageDelegateIndex;
import org.h2.index.PageIndex; import org.h2.index.PageIndex;
import org.h2.message.DbException; import org.h2.message.DbException;
import org.h2.message.Trace; import org.h2.message.Trace;
import org.h2.message.TraceSystem;
import org.h2.result.Row; import org.h2.result.Row;
import org.h2.result.SearchRow; import org.h2.result.SearchRow;
import org.h2.schema.Schema; import org.h2.schema.Schema;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.Table;
import org.h2.table.RegularTable; import org.h2.table.RegularTable;
import org.h2.table.Table;
import org.h2.util.Cache; import org.h2.util.Cache;
import org.h2.util.CacheLRU; import org.h2.util.CacheLRU;
import org.h2.util.CacheObject; import org.h2.util.CacheObject;
...@@ -179,7 +177,7 @@ public class PageStore implements CacheWriter { ...@@ -179,7 +177,7 @@ public class PageStore implements CacheWriter {
private PageDataIndex metaIndex; private PageDataIndex metaIndex;
private IntIntHashMap metaRootPageId = new IntIntHashMap(); private IntIntHashMap metaRootPageId = new IntIntHashMap();
private HashMap<Integer, PageIndex> metaObjects = New.hashMap(); private HashMap<Integer, PageIndex> metaObjects = New.hashMap();
private ArrayList<PageIndex> tempIndexes = New.arrayList(); private HashMap<Integer, PageIndex> tempObjects;
/** /**
* The map of reserved pages, to ensure index head pages * The map of reserved pages, to ensure index head pages
...@@ -220,9 +218,8 @@ public class PageStore implements CacheWriter { ...@@ -220,9 +218,8 @@ public class PageStore implements CacheWriter {
this.accessMode = accessMode; this.accessMode = accessMode;
this.database = database; this.database = database;
trace = database.getTrace(Trace.PAGE_STORE); trace = database.getTrace(Trace.PAGE_STORE);
int test; // if (!fileName.endsWith("reopen.h2.db"))
//if (!fileName.endsWith("reopen.h2.db")) // trace.setLevel(TraceSystem.DEBUG);
//trace.setLevel(TraceSystem.DEBUG);
String cacheType = database.getCacheType(); String cacheType = database.getCacheType();
this.cache = CacheLRU.getCache(this, cacheType, cacheSizeDefault); this.cache = CacheLRU.getCache(this, cacheType, cacheSizeDefault);
systemSession = new Session(database, null, 0); systemSession = new Session(database, null, 0);
...@@ -322,16 +319,19 @@ int test; ...@@ -322,16 +319,19 @@ int test;
} }
private void removeOldTempIndexes() { private void removeOldTempIndexes() {
for (PageIndex index: tempIndexes) { if (tempObjects != null) {
index.truncate(systemSession); metaObjects.putAll(tempObjects);
index.remove(systemSession); for (PageIndex index: tempObjects.values()) {
} if (index.getTable().isTemporary()) {
if (tempIndexes.size() > 0) { index.truncate(systemSession);
index.remove(systemSession);
}
}
systemSession.commit(true); systemSession.commit(true);
tempObjects = null;
} }
metaObjects.clear(); metaObjects.clear();
metaObjects.put(-1, metaIndex); metaObjects.put(-1, metaIndex);
tempIndexes = null;
} }
private void writeIndexRowCounts() { private void writeIndexRowCounts() {
...@@ -361,23 +361,18 @@ int test; ...@@ -361,23 +361,18 @@ int test;
database.checkPowerOff(); database.checkPowerOff();
writeIndexRowCounts(); writeIndexRowCounts();
int test; log.checkpoint();
// writeBack(); writeBack();
// log.checkpoint();
log.checkpoint();
writeBack();
int firstUncommittedSection = getFirstUncommittedSection(); int firstUncommittedSection = getFirstUncommittedSection();
log.removeUntil(firstUncommittedSection); log.removeUntil(firstUncommittedSection);
// write back the free list // write back the free list
writeBack(); writeBack();
int test2; // ensure the free list is backed up again
// ensure the free list is backed up again log.checkpoint();
log.checkpoint();
byte[] empty = new byte[pageSize]; byte[] empty = new byte[pageSize];
...@@ -424,8 +419,8 @@ log.checkpoint(); ...@@ -424,8 +419,8 @@ log.checkpoint();
allocatePage(logFirstTrunkPage); allocatePage(logFirstTrunkPage);
log.openForWriting(logFirstTrunkPage, true); log.openForWriting(logFirstTrunkPage, true);
// ensure the free list is backed up again // ensure the free list is backed up again
log.checkpoint(); log.checkpoint();
} finally { } finally {
recoveryRunning = false; recoveryRunning = false;
...@@ -444,22 +439,16 @@ log.checkpoint(); ...@@ -444,22 +439,16 @@ log.checkpoint();
break; break;
} }
} }
this.checkpoint();
int test; // TODO can most likely be simplified
log.checkpoint(); checkpoint();
log.checkpoint();
writeIndexRowCounts(); writeIndexRowCounts();
log.checkpoint(); log.checkpoint();
writeBack(); writeBack();
commit(systemSession);
int test3; writeBack();
commit(systemSession); log.checkpoint();
writeBack();
log.checkpoint();
// truncate the log // truncate the log
recoveryRunning = true; recoveryRunning = true;
...@@ -510,29 +499,11 @@ log.checkpoint(); ...@@ -510,29 +499,11 @@ log.checkpoint();
Page p = getPage(full); Page p = getPage(full);
if (p != null) { if (p != null) {
trace.debug("move " + p.getPos() + " to " + free); trace.debug("move " + p.getPos() + " to " + free);
long logSection = log.getLogSectionId(), logPos = log.getLogPos();
try { try {
p.moveTo(systemSession, free); p.moveTo(systemSession, free);
} finally { } finally {
changeCount++; changeCount++;
} }
//if (log.getLogSectionId() != logSection || log.getLogPos() != logPos) {
// // commit if an index root page moved
//int test;
//// need to write the log first, then the moved
//// need to write the moved root node,
//// and then we can commit
////log.checkpoint();
//writeBack();
//// commit(systemSession);
//
//int testForceProblem;
//log.checkpoint();
//writeBack();
//log.checkpoint();
//writeBack();
//
// }
} else { } else {
freePage(full); freePage(full);
} }
...@@ -1129,33 +1100,18 @@ log.checkpoint(); ...@@ -1129,33 +1100,18 @@ log.checkpoint();
setReadOnly = true; setReadOnly = true;
} }
} }
// remove temp tables
// PageDataIndex systemTable = (PageDataIndex) metaObjects.get(0);
// isNew = systemTable == null;
// for (Iterator<PageIndex> it = metaObjects.values().iterator(); it.hasNext();) {
// Index openIndex = it.next();
// if (openIndex.getTable().isTemporary()) {
// openIndex.truncate(systemSession);
// openIndex.remove(systemSession);
// removeMetaIndex(openIndex, systemSession);
// it.remove();
// } else {
// openIndex.close(systemSession);
// }
// }
PageDataIndex systemTable = (PageDataIndex) metaObjects.get(0); PageDataIndex systemTable = (PageDataIndex) metaObjects.get(0);
isNew = systemTable == null; isNew = systemTable == null;
for (Iterator<PageIndex> it = metaObjects.values().iterator(); it.hasNext();) { for (PageIndex index : metaObjects.values()) {
PageIndex openIndex = it.next(); if (index.getTable().isTemporary()) {
if (openIndex.getTable().isTemporary()) { // temporary indexes are removed after opening
tempIndexes.add(openIndex); if (tempObjects == null) {
// System.out.println("temp: " + openIndex); tempObjects = New.hashMap();
}
tempObjects.put(index.getId(), index);
} else { } else {
openIndex.close(systemSession); index.close(systemSession);
} }
int test;
} }
allocatePage(PAGE_ID_META_ROOT); allocatePage(PAGE_ID_META_ROOT);
...@@ -1167,14 +1123,10 @@ log.checkpoint(); ...@@ -1167,14 +1123,10 @@ log.checkpoint();
// clear the cache because it contains pages with closed indexes // clear the cache because it contains pages with closed indexes
cache.clear(); cache.clear();
freeLists.clear(); freeLists.clear();
metaObjects.clear(); metaObjects.clear();
metaObjects.put(-1, metaIndex); metaObjects.put(-1, metaIndex);
int test;
for (PageIndex index : tempIndexes) {
metaObjects.put(index.getId(), index);
}
if (setReadOnly) { if (setReadOnly) {
database.setReadOnly(true); database.setReadOnly(true);
} }
...@@ -1356,17 +1308,12 @@ int test; ...@@ -1356,17 +1308,12 @@ int test;
PageIndex index = metaObjects.get(id); PageIndex index = metaObjects.get(id);
int rootPageId = index.getRootPageId(); int rootPageId = index.getRootPageId();
index.getTable().removeIndex(index); index.getTable().removeIndex(index);
int test;
// if (index instanceof PageBtreeIndex) {
if (index instanceof PageBtreeIndex || index instanceof PageDelegateIndex) { if (index instanceof PageBtreeIndex || index instanceof PageDelegateIndex) {
if (index.isTemporary()) { if (index.isTemporary()) {
systemSession.removeLocalTempTableIndex(index); systemSession.removeLocalTempTableIndex(index);
} else { } else {
index.getSchema().remove(index); index.getSchema().remove(index);
} }
// } else if (index instanceof PageDelegateIndex) {
// index.getSchema().remove(index);
} }
index.remove(systemSession); index.remove(systemSession);
metaObjects.remove(id); metaObjects.remove(id);
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论