深入浅出 jackrabbit 十 redolog 和 recovery.docx
2009-09-17 00:00:00 来源:WEB开发网Java代码
private void run() throws IOException {
List actions = redoLog.getActions();
/*找到所有只有开始没有结束的事务,并将其加入到losers这个集合中*/
for (Iterator it = actions.iterator(); it.hasNext();) {
MultiIndex.Action a = (MultiIndex.Action) it.next();
if (a.getType() == MultiIndex.Action.TYPE_START) {
losers.add(new Long(a.getTransactionId()));
} else if (a.getType() == MultiIndex.Action.TYPE_COMMIT) {
losers.remove(new Long(a.getTransactionId()));
}
}
/*找到最后一次成功提交的事务在redolog中的位置*/
int lastSafeVolatileCommit = -1;
Set transactionIds = new HashSet();
for (int i = 0; i < actions.size(); i++) {
MultiIndex.Action a = (MultiIndex.Action) actions.get(i);
if (a.getType() == MultiIndex.Action.TYPE_COMMIT) {
transactionIds.clear();
} else if (a.getType() == MultiIndex.Action.TYPE_VOLATILE_COMMIT) {
transactionIds.retainAll(losers);
// check if transactionIds contains losers
if (transactionIds.size() > 0) {
// found dirty volatile commit
break;
} else {
lastSafeVolatileCommit = i;
}
} else {
transactionIds.add(new Long(a.getTransactionId()));
}
}
/*最后一次成功的事务之后的数据遍历一下,找到脏目录,脏目录是指在一次事务中创建的目录,但是事务最终没有被完整执行,那么这些目录应该被删除掉*/
for (int i = lastSafeVolatileCommit + 1; i < actions.size(); i++) {
MultiIndex.Action a = (MultiIndex.Action) actions.get(i);
if (a.getType() == MultiIndex.Action.TYPE_CREATE_INDEX) {
a.undo(index);
}
}
/*将最后一次正确的事务之前的操作都重新做一遍*/
for (int i = 0; i < actions.size() && i <= lastSafeVolatileCommit; i++) {
MultiIndex.Action a = (MultiIndex.Action) actions.get(i);
switch (a.getType()) {
case MultiIndex.Action.TYPE_ADD_INDEX:
case MultiIndex.Action.TYPE_CREATE_INDEX:
case MultiIndex.Action.TYPE_DELETE_INDEX:
case MultiIndex.Action.TYPE_DELETE_NODE:
// ignore actions by the index merger.
// the previously created index of a merge has been
// deleted because it was considered dirty.
// we are conservative here and let the index merger do
// its work again.
if (a.getTransactionId() == MultiIndex.Action.INTERNAL_TRANS_REPL_INDEXES) {
continue;
}
a.execute(index);
}
}
// now replay the rest until we encounter a loser transaction
for (int i = lastSafeVolatileCommit + 1; i < actions.size(); i++) {
MultiIndex.Action a = (MultiIndex.Action) actions.get(i);
if (losers.contains(new Long(a.getTransactionId()))) {
break;
} else {
// ignore actions by the index merger.
if (a.getTransactionId() == MultiIndex.Action.INTERNAL_TRANS_REPL_INDEXES) {
continue;
}
a.execute(index);
}
}
// now we are consistent again -> flush
index.flush();
index.closeMultiReader();
}
从上面的这段代码可以看出,如果一个事务不完整,那么这个事务的操作将会全部回滚,而事务完整的操作将会被全部重做。
通过这些操作,redolog中的信息被解析出来,并执行,那么就可以找回丢失的数据,并且过滤掉错误的数据。
总结:redolog很重要。
Tags:深入浅出 jackrabbit redolog
编辑录入:爽爽 [复制链接] [打 印]赞助商链接