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

fix deadlock between compact from background and database closure in foreground

Preserve original exception in CreateTable and AlterTableAddConstraint.
上级 a71a0e3d
...@@ -77,9 +77,13 @@ public class AlterTableAddConstraint extends SchemaCommand { ...@@ -77,9 +77,13 @@ public class AlterTableAddConstraint extends SchemaCommand {
try { try {
return tryUpdate(); return tryUpdate();
} catch (DbException e) { } catch (DbException e) {
try {
for (Index index : createdIndexes) { for (Index index : createdIndexes) {
session.getDatabase().removeSchemaObject(session, index); session.getDatabase().removeSchemaObject(session, index);
} }
} catch (Throwable ex) {
e.addSuppressed(ex);
}
throw e; throw e;
} finally { } finally {
getSchema().freeUniqueName(constraintName); getSchema().freeUniqueName(constraintName);
......
...@@ -159,11 +159,15 @@ public class CreateTable extends CommandWithColumns { ...@@ -159,11 +159,15 @@ public class CreateTable extends CommandWithColumns {
} }
} }
} catch (DbException e) { } catch (DbException e) {
try {
db.checkPowerOff(); db.checkPowerOff();
db.removeSchemaObject(session, table); db.removeSchemaObject(session, table);
if (!transactional) { if (!transactional) {
session.commit(true); session.commit(true);
} }
} catch (Throwable ex) {
e.addSuppressed(ex);
}
throw e; throw e;
} }
return 0; return 0;
......
...@@ -293,7 +293,7 @@ public class MVStore { ...@@ -293,7 +293,7 @@ public class MVStore {
/** /**
* Simple lock to ensure that no more than one compaction runs at any given time * Simple lock to ensure that no more than one compaction runs at any given time
*/ */
private final Object compactSync = new Object(); private boolean compactInProgress;
private volatile IllegalStateException panicException; private volatile IllegalStateException panicException;
...@@ -1920,25 +1920,24 @@ public class MVStore { ...@@ -1920,25 +1920,24 @@ public class MVStore {
if (!reuseSpace) { if (!reuseSpace) {
return false; return false;
} }
synchronized (compactSync) {
checkOpen(); checkOpen();
ArrayList<Chunk> old;
// We can't wait fo lock here, because if called from the background thread, // We can't wait fo lock here, because if called from the background thread,
// it might go into deadlock with concurrent database closure // it might go into deadlock with concurrent database closure
// and attempt to stop this thread. // and attempt to stop this thread.
if (storeLock.tryLock()) { if (storeLock.tryLock() && !compactInProgress) {
try { try {
old = findOldChunks(targetFillRate, write); compactInProgress = true;
ArrayList<Chunk> old = findOldChunks(targetFillRate, write);
if (old == null || old.isEmpty()) { if (old == null || old.isEmpty()) {
return false; return false;
} }
compactRewrite(old); compactRewrite(old);
return true; return true;
} finally { } finally {
compactInProgress = false;
storeLock.unlock(); storeLock.unlock();
} }
} }
}
return false; return false;
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论