提交 daa433f0 authored 作者: Andrei Tokar's avatar Andrei Tokar

Exception handling improvements

Assorted minor changes
上级 f796e624
...@@ -808,7 +808,7 @@ public class Database implements DataHandler { ...@@ -808,7 +808,7 @@ public class Database implements DataHandler {
} }
systemSession.commit(true); systemSession.commit(true);
if (mvStore != null) { if (mvStore != null) {
mvStore.initTransactions(); mvStore.getTransactionStore().endLeftoverTransactions();
mvStore.removeTemporaryMaps(objectIds); mvStore.removeTemporaryMaps(objectIds);
} }
recompileInvalidViews(systemSession); recompileInvalidViews(systemSession);
...@@ -1014,29 +1014,31 @@ public class Database implements DataHandler { ...@@ -1014,29 +1014,31 @@ public class Database implements DataHandler {
SearchRow r = meta.getTemplateSimpleRow(false); SearchRow r = meta.getTemplateSimpleRow(false);
r.setValue(0, ValueInt.get(id)); r.setValue(0, ValueInt.get(id));
boolean wasLocked = lockMeta(session); boolean wasLocked = lockMeta(session);
Cursor cursor = metaIdIndex.find(session, r, r); try {
if (cursor.next()) { Cursor cursor = metaIdIndex.find(session, r, r);
if (SysProperties.CHECK) { if (cursor.next()) {
if (lockMode != Constants.LOCK_MODE_OFF && !wasLocked) { if (SysProperties.CHECK) {
throw DbException.throwInternalError(); if (lockMode != Constants.LOCK_MODE_OFF && !wasLocked) {
throw DbException.throwInternalError();
}
}
Row found = cursor.get();
meta.removeRow(session, found);
if (isMultiVersion()) {
// TODO this should work without MVCC, but avoid risks at
// the moment
session.log(meta, UndoLogRecord.DELETE, found);
}
if (SysProperties.CHECK) {
checkMetaFree(session, id);
} }
} }
Row found = cursor.get(); } finally {
meta.removeRow(session, found); if (!wasLocked) {
if (isMultiVersion()) { // must not keep the lock if it was not locked
// TODO this should work without MVCC, but avoid risks at // otherwise updating sequences may cause a deadlock
// the moment unlockMeta(session);
session.log(meta, UndoLogRecord.DELETE, found);
}
if (SysProperties.CHECK) {
checkMetaFree(session, id);
} }
} else if (!wasLocked) {
unlockMetaDebug(session);
// must not keep the lock if it was not locked
// otherwise updating sequences may cause a deadlock
meta.unlock(session);
session.unlock(meta);
} }
objectIds.clear(id); objectIds.clear(id);
} }
...@@ -1333,9 +1335,9 @@ public class Database implements DataHandler { ...@@ -1333,9 +1335,9 @@ public class Database implements DataHandler {
} }
closing = true; closing = true;
} }
} if (!this.isReadOnly()) {
if(!this.isReadOnly()) { removeOrphanedLobs();
removeOrphanedLobs(); }
} }
try { try {
if (systemSession != null) { if (systemSession != null) {
...@@ -1427,81 +1429,84 @@ public class Database implements DataHandler { ...@@ -1427,81 +1429,84 @@ public class Database implements DataHandler {
* @param flush whether writing is allowed * @param flush whether writing is allowed
*/ */
private synchronized void closeOpenFilesAndUnlock(boolean flush) { private synchronized void closeOpenFilesAndUnlock(boolean flush) {
stopWriter(); try {
if (pageStore != null) { stopWriter();
if (flush) { if (pageStore != null) {
try { if (flush) {
pageStore.checkpoint(); try {
if (!readOnly) { pageStore.checkpoint();
lockMeta(pageStore.getPageStoreSession()); if (!readOnly) {
pageStore.compact(compactMode); lockMeta(pageStore.getPageStoreSession());
unlockMeta(pageStore.getPageStoreSession()); pageStore.compact(compactMode);
} unlockMeta(pageStore.getPageStoreSession());
} catch (DbException e) {
if (ASSERT) {
int code = e.getErrorCode();
if (code != ErrorCode.DATABASE_IS_CLOSED &&
code != ErrorCode.LOCK_TIMEOUT_1 &&
code != ErrorCode.IO_EXCEPTION_2) {
e.printStackTrace();
} }
} catch (DbException e) {
if (ASSERT) {
int code = e.getErrorCode();
if (code != ErrorCode.DATABASE_IS_CLOSED &&
code != ErrorCode.LOCK_TIMEOUT_1 &&
code != ErrorCode.IO_EXCEPTION_2) {
e.printStackTrace();
}
}
trace.error(e, "close");
} catch (Throwable t) {
if (ASSERT) {
t.printStackTrace();
}
trace.error(t, "close");
} }
trace.error(e, "close");
} catch (Throwable t) {
if (ASSERT) {
t.printStackTrace();
}
trace.error(t, "close");
} }
} }
} reconnectModified(false);
reconnectModified(false); if (mvStore != null && mvStore.getStore() != null && !mvStore.getStore().isClosed()) {
if (mvStore != null && !mvStore.getStore().isClosed()) { long maxCompactTime = dbSettings.maxCompactTime;
long maxCompactTime = dbSettings.maxCompactTime; if (compactMode == CommandInterface.SHUTDOWN_COMPACT) {
if (compactMode == CommandInterface.SHUTDOWN_COMPACT) { mvStore.compactFile(dbSettings.maxCompactTime);
mvStore.compactFile(dbSettings.maxCompactTime); } else if (compactMode == CommandInterface.SHUTDOWN_DEFRAG) {
} else if (compactMode == CommandInterface.SHUTDOWN_DEFRAG) { maxCompactTime = Long.MAX_VALUE;
maxCompactTime = Long.MAX_VALUE; } else if (getSettings().defragAlways) {
} else if (getSettings().defragAlways) { maxCompactTime = Long.MAX_VALUE;
maxCompactTime = Long.MAX_VALUE; }
mvStore.close(maxCompactTime);
}
if (systemSession != null) {
systemSession.close();
systemSession = null;
}
if (lobSession != null) {
lobSession.close();
lobSession = null;
}
closeFiles();
if (persistent && lock == null &&
fileLockMethod != FileLockMethod.NO &&
fileLockMethod != FileLockMethod.FS) {
// everything already closed (maybe in checkPowerOff)
// don't delete temp files in this case because
// the database could be open now (even from within another process)
return;
} }
mvStore.close(maxCompactTime); if (persistent) {
} deleteOldTempFiles();
closeFiles(); }
if (persistent && lock == null && } finally {
fileLockMethod != FileLockMethod.NO && if (lock != null) {
fileLockMethod != FileLockMethod.FS) { if (fileLockMethod == FileLockMethod.SERIALIZED) {
// everything already closed (maybe in checkPowerOff) // wait before deleting the .lock file,
// don't delete temp files in this case because // otherwise other connections can not detect that
// the database could be open now (even from within another process) if (lock.load().containsKey("changePending")) {
return; try {
} Thread.sleep(TimeUnit.NANOSECONDS
if (persistent) { .toMillis((long) (reconnectCheckDelayNs * 1.1)));
deleteOldTempFiles(); } catch (InterruptedException e) {
} trace.error(e, "close");
if (systemSession != null) { }
systemSession.close();
systemSession = null;
}
if (lobSession != null) {
lobSession.close();
lobSession = null;
}
if (lock != null) {
if (fileLockMethod == FileLockMethod.SERIALIZED) {
// wait before deleting the .lock file,
// otherwise other connections can not detect that
if (lock.load().containsKey("changePending")) {
try {
Thread.sleep(TimeUnit.NANOSECONDS
.toMillis((long) (reconnectCheckDelayNs * 1.1)));
} catch (InterruptedException e) {
trace.error(e, "close");
} }
} }
lock.unlock();
lock = null;
} }
lock.unlock();
lock = null;
} }
} }
...@@ -1946,7 +1951,6 @@ public class Database implements DataHandler { ...@@ -1946,7 +1951,6 @@ public class Database implements DataHandler {
t.getSQL()); t.getSQL());
} }
obj.removeChildrenAndResources(session); obj.removeChildrenAndResources(session);
} }
removeMeta(session, id); removeMeta(session, id);
} }
...@@ -2550,6 +2554,7 @@ public class Database implements DataHandler { ...@@ -2550,6 +2554,7 @@ public class Database implements DataHandler {
* Immediately close the database. * Immediately close the database.
*/ */
public void shutdownImmediately() { public void shutdownImmediately() {
closing = true;
setPowerOffCount(1); setPowerOffCount(1);
try { try {
checkPowerOff(); checkPowerOff();
......
...@@ -511,16 +511,18 @@ public class MVStore { ...@@ -511,16 +511,18 @@ public class MVStore {
M map = (M) getMap(id); M map = (M) getMap(id);
if (map == null) { if (map == null) {
String configAsString = meta.get(MVMap.getMapKey(id)); String configAsString = meta.get(MVMap.getMapKey(id));
if(configAsString != null) { HashMap<String, Object> config;
HashMap<String, Object> config = if (configAsString != null) {
new HashMap<String, Object>(DataUtils.parseMap(configAsString)); config = new HashMap<String, Object>(DataUtils.parseMap(configAsString));
config.put("id", id); } else {
map = builder.create(this, config); config = new HashMap<>();
map.init();
long root = getRootPos(meta, id);
map.setRootPos(root, lastStoredVersion);
maps.put(id, map);
} }
config.put("id", id);
map = builder.create(this, config);
map.init();
long root = getRootPos(meta, id);
map.setRootPos(root, lastStoredVersion);
maps.put(id, map);
} }
return map; return map;
} finally { } finally {
......
...@@ -246,21 +246,6 @@ public class MVTableEngine implements TableEngine { ...@@ -246,21 +246,6 @@ public class MVTableEngine implements TableEngine {
store.closeImmediately(); store.closeImmediately();
} }
/**
* Commit all transactions that are in the committing state, and
* rollback all open transactions.
*/
public void initTransactions() {
List<Transaction> list = transactionStore.getOpenTransactions();
for (Transaction t : list) {
if (t.getStatus() == Transaction.STATUS_COMMITTED) {
t.commit();
} else if (t.getStatus() != Transaction.STATUS_PREPARED) {
t.rollback();
}
}
}
/** /**
* Remove all temporary maps. * Remove all temporary maps.
* *
......
...@@ -147,14 +147,6 @@ public class TransactionStore { ...@@ -147,14 +147,6 @@ public class TransactionStore {
*/ */
public void init() { public void init() {
if (!init) { if (!init) {
// remove all temporary maps
for (String mapName : store.getMapNames()) {
if (mapName.startsWith("temp.")) {
MVMap<Object, Integer> temp = openTempMap(mapName);
store.removeMap(temp);
}
}
for (String mapName : store.getMapNames()) { for (String mapName : store.getMapNames()) {
if (mapName.startsWith(UNDO_LOG_NAME_PEFIX)) { if (mapName.startsWith(UNDO_LOG_NAME_PEFIX)) {
if (store.hasData(mapName)) { if (store.hasData(mapName)) {
...@@ -165,13 +157,15 @@ public class TransactionStore { ...@@ -165,13 +157,15 @@ public class TransactionStore {
int status; int status;
String name; String name;
if (data == null) { if (data == null) {
status = mapName.charAt(UNDO_LOG_NAME_PEFIX.length()) == UNDO_LOG_OPEN ? status = Transaction.STATUS_OPEN;
Transaction.STATUS_OPEN : Transaction.STATUS_COMMITTED;
name = null; name = null;
} else { } else {
status = (Integer) data[0]; status = (Integer) data[0];
name = (String) data[1]; name = (String) data[1];
} }
if (mapName.charAt(UNDO_LOG_NAME_PEFIX.length()) == UNDO_LOG_COMMITTED) {
status = Transaction.STATUS_COMMITTED;
}
MVMap<Long, Object[]> undoLog = store.openMap(mapName, undoLogBuilder); MVMap<Long, Object[]> undoLog = store.openMap(mapName, undoLogBuilder);
undoLogs[transactionId] = undoLog; undoLogs[transactionId] = undoLog;
Long lastUndoKey = undoLog.lastKey(); Long lastUndoKey = undoLog.lastKey();
...@@ -187,6 +181,21 @@ public class TransactionStore { ...@@ -187,6 +181,21 @@ public class TransactionStore {
} }
} }
/**
* Commit all transactions that are in the committed state, and
* rollback all open transactions.
*/
public void endLeftoverTransactions() {
List<Transaction> list = getOpenTransactions();
for (Transaction t : list) {
if (t.getStatus() == Transaction.STATUS_COMMITTED) {
t.commit();
} else if (t.getStatus() != Transaction.STATUS_PREPARED) {
t.rollback();
}
}
}
/** /**
* Set the maximum transaction id, after which ids are re-used. If the old * Set the maximum transaction id, after which ids are re-used. If the old
* transaction is still in use when re-using an old id, the new transaction * transaction is still in use when re-using an old id, the new transaction
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论