提交 9366c741 authored 作者: Thomas Mueller's avatar Thomas Mueller

MVStore: the Recover tool can now deal with more types of corruption in the…

MVStore: the Recover tool can now deal with more types of corruption in the file. MVStore: the TransactionStore now first needs to be initialized before it can be used.
上级 c5d33cf2
...@@ -17,7 +17,9 @@ Change Log ...@@ -17,7 +17,9 @@ Change Log
<h1>Change Log</h1> <h1>Change Log</h1>
<h2>Next Version (unreleased)</h2> <h2>Next Version (unreleased)</h2>
<ul><li>Views and derived tables with equality and range conditions on the same columns <ul><li>MVStore: the Recover tool can now deal with more types of corruption in the file.
</li><li>MVStore: the TransactionStore now first needs to be initialized before it can be used.
</li><li>Views and derived tables with equality and range conditions on the same columns
did not work properly. example: select x from (select x from (select 1 as x) did not work properly. example: select x from (select x from (select 1 as x)
where x &gt; 0 and x &lt; 2) where x = 1 where x &gt; 0 and x &lt; 2) where x = 1
</li><li>The database URL setting PAGE_SIZE setting is now also used for the MVStore. </li><li>The database URL setting PAGE_SIZE setting is now also used for the MVStore.
......
...@@ -88,6 +88,12 @@ public class DataUtils { ...@@ -88,6 +88,12 @@ public class DataUtils {
*/ */
public static final int ERROR_TRANSACTION_STILL_OPEN = 102; public static final int ERROR_TRANSACTION_STILL_OPEN = 102;
/**
* The transaction store is in an illegal state (for example, not yet
* initialized).
*/
public static final int ERROR_TRANSACTION_ILLEGAL_STATE = 103;
/** /**
* The type for leaf page. * The type for leaf page.
*/ */
......
...@@ -163,6 +163,7 @@ public class MVTableEngine implements TableEngine { ...@@ -163,6 +163,7 @@ public class MVTableEngine implements TableEngine {
this.transactionStore = new TransactionStore( this.transactionStore = new TransactionStore(
store, store,
new ValueDataType(null, db, null)); new ValueDataType(null, db, null));
transactionStore.init();
} }
public MVStore getStore() { public MVStore getStore() {
......
...@@ -57,6 +57,8 @@ public class TransactionStore { ...@@ -57,6 +57,8 @@ public class TransactionStore {
private final DataType dataType; private final DataType dataType;
private boolean init;
private int lastTransactionId; private int lastTransactionId;
private int maxTransactionId = 0xffff; private int maxTransactionId = 0xffff;
...@@ -94,19 +96,33 @@ public class TransactionStore { ...@@ -94,19 +96,33 @@ public class TransactionStore {
new MVMap.Builder<Long, Object[]>(). new MVMap.Builder<Long, Object[]>().
valueType(undoLogValueType); valueType(undoLogValueType);
undoLog = store.openMap("undoLog", builder); undoLog = store.openMap("undoLog", builder);
// remove all temporary maps
if (undoLog.getValueType() != undoLogValueType) { if (undoLog.getValueType() != undoLogValueType) {
throw DataUtils.newIllegalStateException( throw DataUtils.newIllegalStateException(
DataUtils.ERROR_TRANSACTION_CORRUPT, DataUtils.ERROR_TRANSACTION_CORRUPT,
"Undo map open with a different value type"); "Undo map open with a different value type");
} }
}
/**
* Initialize the store. This is needed before a transaction can be opened.
* If the transaction store is corrupt, this method can throw an exception,
* in which case the store can only be used for reading.
*/
public synchronized void init() {
init = true;
// remove all temporary maps
for (String mapName : store.getMapNames()) { for (String mapName : store.getMapNames()) {
if (mapName.startsWith("temp.")) { if (mapName.startsWith("temp.")) {
MVMap<Object, Integer> temp = openTempMap(mapName); MVMap<Object, Integer> temp = openTempMap(mapName);
store.removeMap(temp); store.removeMap(temp);
} }
} }
init(); synchronized (undoLog) {
if (undoLog.size() > 0) {
Long key = undoLog.firstKey();
lastTransactionId = getTransactionId(key);
}
}
} }
/** /**
...@@ -155,15 +171,6 @@ public class TransactionStore { ...@@ -155,15 +171,6 @@ public class TransactionStore {
return operationId & ((1L << 40) - 1); return operationId & ((1L << 40) - 1);
} }
private synchronized void init() {
synchronized (undoLog) {
if (undoLog.size() > 0) {
Long key = undoLog.firstKey();
lastTransactionId = getTransactionId(key);
}
}
}
/** /**
* Get the list of unclosed transactions that have pending writes. * Get the list of unclosed transactions that have pending writes.
* *
...@@ -213,6 +220,11 @@ public class TransactionStore { ...@@ -213,6 +220,11 @@ public class TransactionStore {
* @return the transaction * @return the transaction
*/ */
public synchronized Transaction begin() { public synchronized Transaction begin() {
if (!init) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_TRANSACTION_ILLEGAL_STATE,
"Not initialized");
}
int transactionId = ++lastTransactionId; int transactionId = ++lastTransactionId;
if (lastTransactionId >= maxTransactionId) { if (lastTransactionId >= maxTransactionId) {
lastTransactionId = 0; lastTransactionId = 0;
......
...@@ -591,6 +591,11 @@ public class Recover extends Tool implements DataHandler { ...@@ -591,6 +591,11 @@ public class Recover extends Tool implements DataHandler {
dumpMeta(writer, mv); dumpMeta(writer, mv);
writer.println("-- Tables"); writer.println("-- Tables");
TransactionStore store = new TransactionStore(mv); TransactionStore store = new TransactionStore(mv);
try {
store.init();
} catch (Throwable e) {
writeError(writer, e);
}
try { try {
for (String mapName : mv.getMapNames()) { for (String mapName : mv.getMapNames()) {
if (!mapName.startsWith("table.")) { if (!mapName.startsWith("table.")) {
......
...@@ -424,6 +424,7 @@ public class TestMVTableEngine extends TestBase { ...@@ -424,6 +424,7 @@ public class TestMVTableEngine extends TestBase {
MVStore store = MVStore.open(file); MVStore store = MVStore.open(file);
TransactionStore t = new TransactionStore(store); TransactionStore t = new TransactionStore(store);
t.init();
assertEquals(0, t.getOpenTransactions().size()); assertEquals(0, t.getOpenTransactions().size());
store.close(); store.close();
} }
......
...@@ -65,6 +65,7 @@ public class TestTransactionStore extends TestBase { ...@@ -65,6 +65,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts; TransactionStore ts;
s = MVStore.open(null); s = MVStore.open(null);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
Transaction tx1 = ts.begin(); Transaction tx1 = ts.begin();
TransactionMap<Integer, Integer> map1 = tx1.openMap("data"); TransactionMap<Integer, Integer> map1 = tx1.openMap("data");
...@@ -98,6 +99,7 @@ public class TestTransactionStore extends TestBase { ...@@ -98,6 +99,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts; TransactionStore ts;
s = MVStore.open(null); s = MVStore.open(null);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
Transaction tx1 = ts.begin(); Transaction tx1 = ts.begin();
TransactionMap<Integer, Integer> map1 = tx1.openMap("data"); TransactionMap<Integer, Integer> map1 = tx1.openMap("data");
...@@ -125,6 +127,7 @@ public class TestTransactionStore extends TestBase { ...@@ -125,6 +127,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts; TransactionStore ts;
s = MVStore.open(null); s = MVStore.open(null);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
Transaction tx0 = ts.begin(); Transaction tx0 = ts.begin();
TransactionMap<Integer, Integer> map0 = tx0.openMap("data"); TransactionMap<Integer, Integer> map0 = tx0.openMap("data");
...@@ -149,6 +152,7 @@ public class TestTransactionStore extends TestBase { ...@@ -149,6 +152,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts; TransactionStore ts;
s = MVStore.open(null); s = MVStore.open(null);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
ts.setMaxTransactionId(16); ts.setMaxTransactionId(16);
for (int i = 0, j = 1; i < 64; i++) { for (int i = 0, j = 1; i < 64; i++) {
Transaction t = ts.begin(); Transaction t = ts.begin();
...@@ -161,6 +165,7 @@ public class TestTransactionStore extends TestBase { ...@@ -161,6 +165,7 @@ public class TestTransactionStore extends TestBase {
} }
s = MVStore.open(null); s = MVStore.open(null);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
ts.setMaxTransactionId(16); ts.setMaxTransactionId(16);
ArrayList<Transaction> fifo = New.arrayList(); ArrayList<Transaction> fifo = New.arrayList();
int open = 0; int open = 0;
...@@ -197,6 +202,7 @@ public class TestTransactionStore extends TestBase { ...@@ -197,6 +202,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName); s = MVStore.open(fileName);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
tx = ts.begin(); tx = ts.begin();
s.setReuseSpace(false); s.setReuseSpace(false);
m = tx.openMap("test"); m = tx.openMap("test");
...@@ -260,6 +266,7 @@ public class TestTransactionStore extends TestBase { ...@@ -260,6 +266,7 @@ public class TestTransactionStore extends TestBase {
private void testGetModifiedMaps() { private void testGetModifiedMaps() {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx; Transaction tx;
TransactionMap<String, String> m1, m2, m3; TransactionMap<String, String> m1, m2, m3;
long sp; long sp;
...@@ -329,6 +336,7 @@ public class TestTransactionStore extends TestBase { ...@@ -329,6 +336,7 @@ public class TestTransactionStore extends TestBase {
private void testKeyIterator() { private void testKeyIterator() {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx, tx2; Transaction tx, tx2;
TransactionMap<String, String> m, m2; TransactionMap<String, String> m, m2;
Iterator<String> it, it2; Iterator<String> it, it2;
...@@ -382,6 +390,8 @@ public class TestTransactionStore extends TestBase { ...@@ -382,6 +390,8 @@ public class TestTransactionStore extends TestBase {
private void testMultiStatement() { private void testMultiStatement() {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx; Transaction tx;
TransactionMap<String, String> m; TransactionMap<String, String> m;
long startUpdate; long startUpdate;
...@@ -470,6 +480,7 @@ public class TestTransactionStore extends TestBase { ...@@ -470,6 +480,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName); s = MVStore.open(fileName);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
tx = ts.begin(); tx = ts.begin();
assertEquals(null, tx.getName()); assertEquals(null, tx.getName());
tx.setName("first transaction"); tx.setName("first transaction");
...@@ -489,6 +500,7 @@ public class TestTransactionStore extends TestBase { ...@@ -489,6 +500,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName); s = MVStore.open(fileName);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
tx = ts.begin(); tx = ts.begin();
assertEquals(2, tx.getId()); assertEquals(2, tx.getId());
m = tx.openMap("test"); m = tx.openMap("test");
...@@ -507,6 +519,7 @@ public class TestTransactionStore extends TestBase { ...@@ -507,6 +519,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName); s = MVStore.open(fileName);
ts = new TransactionStore(s); ts = new TransactionStore(s);
ts.init();
tx = ts.begin(); tx = ts.begin();
m = tx.openMap("test"); m = tx.openMap("test");
assertEquals(2, tx.getId()); assertEquals(2, tx.getId());
...@@ -531,6 +544,7 @@ public class TestTransactionStore extends TestBase { ...@@ -531,6 +544,7 @@ public class TestTransactionStore extends TestBase {
private void testSavepoint() { private void testSavepoint() {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx; Transaction tx;
TransactionMap<String, String> m; TransactionMap<String, String> m;
...@@ -584,6 +598,7 @@ public class TestTransactionStore extends TestBase { ...@@ -584,6 +598,7 @@ public class TestTransactionStore extends TestBase {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
for (int i = 0; i < connectionCount; i++) { for (int i = 0; i < connectionCount; i++) {
Statement stat = statements.get(i); Statement stat = statements.get(i);
// 100 ms to avoid blocking (the test is single threaded) // 100 ms to avoid blocking (the test is single threaded)
...@@ -717,6 +732,7 @@ public class TestTransactionStore extends TestBase { ...@@ -717,6 +732,7 @@ public class TestTransactionStore extends TestBase {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx1, tx2; Transaction tx1, tx2;
TransactionMap<String, String> m1, m2; TransactionMap<String, String> m1, m2;
...@@ -789,6 +805,7 @@ public class TestTransactionStore extends TestBase { ...@@ -789,6 +805,7 @@ public class TestTransactionStore extends TestBase {
MVStore s = MVStore.open(null); MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s); TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx; Transaction tx;
TransactionMap<String, String> m; TransactionMap<String, String> m;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论