提交 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
<h1>Change Log</h1>
<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)
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.
......
......@@ -88,6 +88,12 @@ public class DataUtils {
*/
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.
*/
......
......@@ -163,6 +163,7 @@ public class MVTableEngine implements TableEngine {
this.transactionStore = new TransactionStore(
store,
new ValueDataType(null, db, null));
transactionStore.init();
}
public MVStore getStore() {
......
......@@ -54,9 +54,11 @@ public class TransactionStore {
*/
private HashMap<Integer, MVMap<Object, VersionedValue>> maps =
New.hashMap();
private final DataType dataType;
private boolean init;
private int lastTransactionId;
private int maxTransactionId = 0xffff;
......@@ -94,19 +96,33 @@ public class TransactionStore {
new MVMap.Builder<Long, Object[]>().
valueType(undoLogValueType);
undoLog = store.openMap("undoLog", builder);
// remove all temporary maps
if (undoLog.getValueType() != undoLogValueType) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_TRANSACTION_CORRUPT,
"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()) {
if (mapName.startsWith("temp.")) {
MVMap<Object, Integer> temp = openTempMap(mapName);
store.removeMap(temp);
}
}
init();
synchronized (undoLog) {
if (undoLog.size() > 0) {
Long key = undoLog.firstKey();
lastTransactionId = getTransactionId(key);
}
}
}
/**
......@@ -155,15 +171,6 @@ public class TransactionStore {
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.
*
......@@ -213,6 +220,11 @@ public class TransactionStore {
* @return the transaction
*/
public synchronized Transaction begin() {
if (!init) {
throw DataUtils.newIllegalStateException(
DataUtils.ERROR_TRANSACTION_ILLEGAL_STATE,
"Not initialized");
}
int transactionId = ++lastTransactionId;
if (lastTransactionId >= maxTransactionId) {
lastTransactionId = 0;
......
......@@ -591,6 +591,11 @@ public class Recover extends Tool implements DataHandler {
dumpMeta(writer, mv);
writer.println("-- Tables");
TransactionStore store = new TransactionStore(mv);
try {
store.init();
} catch (Throwable e) {
writeError(writer, e);
}
try {
for (String mapName : mv.getMapNames()) {
if (!mapName.startsWith("table.")) {
......
......@@ -424,6 +424,7 @@ public class TestMVTableEngine extends TestBase {
MVStore store = MVStore.open(file);
TransactionStore t = new TransactionStore(store);
t.init();
assertEquals(0, t.getOpenTransactions().size());
store.close();
}
......
......@@ -65,6 +65,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts;
s = MVStore.open(null);
ts = new TransactionStore(s);
ts.init();
Transaction tx1 = ts.begin();
TransactionMap<Integer, Integer> map1 = tx1.openMap("data");
......@@ -98,6 +99,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts;
s = MVStore.open(null);
ts = new TransactionStore(s);
ts.init();
Transaction tx1 = ts.begin();
TransactionMap<Integer, Integer> map1 = tx1.openMap("data");
......@@ -125,6 +127,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts;
s = MVStore.open(null);
ts = new TransactionStore(s);
ts.init();
Transaction tx0 = ts.begin();
TransactionMap<Integer, Integer> map0 = tx0.openMap("data");
......@@ -149,6 +152,7 @@ public class TestTransactionStore extends TestBase {
TransactionStore ts;
s = MVStore.open(null);
ts = new TransactionStore(s);
ts.init();
ts.setMaxTransactionId(16);
for (int i = 0, j = 1; i < 64; i++) {
Transaction t = ts.begin();
......@@ -161,6 +165,7 @@ public class TestTransactionStore extends TestBase {
}
s = MVStore.open(null);
ts = new TransactionStore(s);
ts.init();
ts.setMaxTransactionId(16);
ArrayList<Transaction> fifo = New.arrayList();
int open = 0;
......@@ -197,6 +202,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName);
ts = new TransactionStore(s);
ts.init();
tx = ts.begin();
s.setReuseSpace(false);
m = tx.openMap("test");
......@@ -260,6 +266,7 @@ public class TestTransactionStore extends TestBase {
private void testGetModifiedMaps() {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx;
TransactionMap<String, String> m1, m2, m3;
long sp;
......@@ -329,6 +336,7 @@ public class TestTransactionStore extends TestBase {
private void testKeyIterator() {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx, tx2;
TransactionMap<String, String> m, m2;
Iterator<String> it, it2;
......@@ -382,6 +390,8 @@ public class TestTransactionStore extends TestBase {
private void testMultiStatement() {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx;
TransactionMap<String, String> m;
long startUpdate;
......@@ -470,6 +480,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName);
ts = new TransactionStore(s);
ts.init();
tx = ts.begin();
assertEquals(null, tx.getName());
tx.setName("first transaction");
......@@ -489,6 +500,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName);
ts = new TransactionStore(s);
ts.init();
tx = ts.begin();
assertEquals(2, tx.getId());
m = tx.openMap("test");
......@@ -507,6 +519,7 @@ public class TestTransactionStore extends TestBase {
s = MVStore.open(fileName);
ts = new TransactionStore(s);
ts.init();
tx = ts.begin();
m = tx.openMap("test");
assertEquals(2, tx.getId());
......@@ -531,6 +544,7 @@ public class TestTransactionStore extends TestBase {
private void testSavepoint() {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx;
TransactionMap<String, String> m;
......@@ -584,6 +598,7 @@ public class TestTransactionStore extends TestBase {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
for (int i = 0; i < connectionCount; i++) {
Statement stat = statements.get(i);
// 100 ms to avoid blocking (the test is single threaded)
......@@ -717,6 +732,7 @@ public class TestTransactionStore extends TestBase {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx1, tx2;
TransactionMap<String, String> m1, m2;
......@@ -789,6 +805,7 @@ public class TestTransactionStore extends TestBase {
MVStore s = MVStore.open(null);
TransactionStore ts = new TransactionStore(s);
ts.init();
Transaction tx;
TransactionMap<String, String> m;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论