While digging source code in MVStore, I found that the rollback has two
different code paths in MVStore. The two different code paths is the same
effect in my opinion which both of them can recover after suddenly crash.
However one of them is more simple and easy to understand.
The first one is when client send 'rollback' command to server, MVStore
execute like this :
Session.rollbackTo()
Iterator<Change> it = transaction.getChanges(savepointId);
while (it.hasNext()) {
Change c = it.next();
MVTable t = tableMap.get(c.mapName);
if (t != null) {
long key = ((ValueLong) c.key).getLong();
ValueArray value = (ValueArray) c.value;
short op;
Row row;
if (value == null) {
op = UndoLogRecord.INSERT;
row = t.getRow(this, key);
} else {
op = UndoLogRecord.DELETE;
row = new Row(value.getList(), Row.MEMORY_CALCULATE);
}
row.setKey(key);
UndoLogRecord log = new UndoLogRecord(t, op, row);
log.undo(this);
}
Note that the last line: log.undo(this) will undo the change and add
another undo log. After undo all the changes, transaction need to commit
again to remove all the undo log which is twice as many as before.
The second code path is in the recover process during H2 restart from
crash. H2 will undo all the transactions which is mark as STATUS_OPEN. The
detail is as follow:
TransactionStore.rollbackTo()
for (long logId = maxLogId - 1; logId >= toLogId; logId--) {
Long undoKey = getOperationId(t.getId(), logId);
Object[] op = undoLog.get(undoKey);
if (op == null) {
// partially rolled back: load previous
undoKey = undoLog.floorKey(undoKey);
if (undoKey == null ||
getTransactionId(undoKey) != t.getId()) {
break;
}
logId = getLogId(undoKey) + 1;
continue;
}
int mapId = ((Integer) op[0]).intValue();
MVMap<Object, VersionedValue> map = openMap(mapId);
if (map != null) {
Object key = op[1];
VersionedValue oldValue = (VersionedValue) op[2];
if (oldValue == null) {
// this transaction added the value
map.remove(key);
} else {
// this transaction updated the value
map.put(key, oldValue);
}
}
undoLog.remove(undoKey);
}
This looks like the first one except it undo the change and remove the
undo log at the same time which is more simple and easy to understand.
Anyway, I think it's no need to add more undo log during undo.
So I think these two code paths have the same effect but the second one
is more simple. However I suspect is there anything lack of consider about
these two? If have, please lighten me. Thanks in advance
--
You received this message because you are subscribed to the Google Groups "H2
Database" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/h2-database.
For more options, visit https://groups.google.com/d/optout.