use of org.h2.tools.Recover in project h2database by h2database.
the class TestRecovery method testCompressedAndUncompressed.
private void testCompressedAndUncompressed() throws SQLException {
DeleteDbFiles.execute(getBaseDir(), "recovery", true);
DeleteDbFiles.execute(getBaseDir(), "recovery2", true);
org.h2.Driver.load();
Connection conn = getConnection("recovery");
Statement stat = conn.createStatement();
stat.execute("create table test(id int primary key, data clob)");
stat.execute("insert into test values(1, space(10000))");
stat.execute("set compress_lob lzf");
stat.execute("insert into test values(2, space(10000))");
conn.close();
Recover rec = new Recover();
rec.runTool("-dir", getBaseDir(), "-db", "recovery");
Connection conn2 = getConnection("recovery2");
Statement stat2 = conn2.createStatement();
String name = "recovery.h2.sql";
stat2.execute("runscript from '" + getBaseDir() + "/" + name + "'");
stat2.execute("select * from test");
conn2.close();
conn = getConnection("recovery");
stat = conn.createStatement();
conn2 = getConnection("recovery2");
stat2 = conn2.createStatement();
assertEqualDatabases(stat, stat2);
conn.close();
conn2.close();
DeleteDbFiles.execute(getBaseDir(), "recovery", true);
DeleteDbFiles.execute(getBaseDir(), "recovery2", true);
}
use of org.h2.tools.Recover in project h2database by h2database.
the class TestRecovery method testRunScript.
private void testRunScript() throws SQLException {
DeleteDbFiles.execute(getBaseDir(), "recovery", true);
DeleteDbFiles.execute(getBaseDir(), "recovery2", true);
org.h2.Driver.load();
Connection conn = getConnection("recovery");
Statement stat = conn.createStatement();
stat.execute("create table \"Joe\"\"s Table\" as " + "select 1");
stat.execute("create table test as " + "select * from system_range(1, 100)");
stat.execute("create view \"TEST VIEW OF TABLE TEST\" as " + "select * from test");
stat.execute("create table a(id int primary key) as " + "select * from system_range(1, 100)");
stat.execute("create table b(id int references a(id)) as " + "select * from system_range(1, 100)");
stat.execute("create table lob(c clob, b blob) as " + "select space(10000) || 'end', SECURE_RAND(10000)");
stat.execute("create table d(d varchar) as " + "select space(10000) || 'end'");
stat.execute("alter table a add foreign key(id) references b(id)");
// all rows have the same value - so that SCRIPT can't re-order the rows
stat.execute("create table e(id varchar) as " + "select space(10) from system_range(1, 1000)");
stat.execute("create index idx_e_id on e(id)");
conn.close();
Recover rec = new Recover();
ByteArrayOutputStream buff = new ByteArrayOutputStream();
rec.setOut(new PrintStream(buff));
rec.runTool("-dir", getBaseDir(), "-db", "recovery", "-trace");
String out = new String(buff.toByteArray());
assertContains(out, "Created file");
Connection conn2 = getConnection("recovery2");
Statement stat2 = conn2.createStatement();
String name = "recovery.h2.sql";
stat2.execute("runscript from '" + getBaseDir() + "/" + name + "'");
stat2.execute("select * from test");
conn2.close();
conn = getConnection("recovery");
stat = conn.createStatement();
conn2 = getConnection("recovery2");
stat2 = conn2.createStatement();
assertEqualDatabases(stat, stat2);
conn.close();
conn2.close();
Recover.execute(getBaseDir(), "recovery");
deleteDb("recovery");
deleteDb("recovery2");
FileUtils.delete(getBaseDir() + "/recovery.h2.sql");
String dir = getBaseDir() + "/recovery.lobs.db";
FileUtils.deleteRecursive(dir, false);
}
use of org.h2.tools.Recover in project h2database by h2database.
the class TestWeb method testTools.
private void testTools() throws Exception {
if (config.memory || config.cipher != null) {
return;
}
deleteDb(getTestName());
Connection conn = getConnection(getTestName());
conn.createStatement().execute("create table test(id int) as select 1");
conn.close();
Server server = new Server();
server.setOut(new PrintStream(new ByteArrayOutputStream()));
server.runTool("-web", "-webPort", "8182", "-properties", "null", "-tcp", "-tcpPort", "9101");
try {
String url = "http://localhost:8182";
WebClient client;
String result;
client = new WebClient();
result = client.get(url);
client.readSessionId(result);
result = client.get(url, "tools.jsp");
FileUtils.delete(getBaseDir() + "/backup.zip");
result = client.get(url, "tools.do?tool=Backup&args=-dir," + getBaseDir() + ",-db," + getTestName() + ",-file," + getBaseDir() + "/backup.zip");
deleteDb(getTestName());
assertTrue(FileUtils.exists(getBaseDir() + "/backup.zip"));
result = client.get(url, "tools.do?tool=DeleteDbFiles&args=-dir," + getBaseDir() + ",-db," + getTestName());
String fn = getBaseDir() + "/" + getTestName();
if (config.mvStore) {
fn += Constants.SUFFIX_MV_FILE;
} else {
fn += Constants.SUFFIX_PAGE_FILE;
}
assertFalse(FileUtils.exists(fn));
result = client.get(url, "tools.do?tool=Restore&args=-dir," + getBaseDir() + ",-db," + getTestName() + ",-file," + getBaseDir() + "/backup.zip");
assertTrue(FileUtils.exists(fn));
FileUtils.delete(getBaseDir() + "/web.h2.sql");
FileUtils.delete(getBaseDir() + "/backup.zip");
result = client.get(url, "tools.do?tool=Recover&args=-dir," + getBaseDir() + ",-db," + getTestName());
assertTrue(FileUtils.exists(getBaseDir() + "/" + getTestName() + ".h2.sql"));
FileUtils.delete(getBaseDir() + "/web.h2.sql");
result = client.get(url, "tools.do?tool=RunScript&args=-script," + getBaseDir() + "/" + getTestName() + ".h2.sql,-url," + getURL(getTestName(), true) + ",-user," + getUser() + ",-password," + getPassword());
FileUtils.delete(getBaseDir() + "/" + getTestName() + ".h2.sql");
assertTrue(FileUtils.exists(fn));
deleteDb(getTestName());
} finally {
server.shutdown();
}
}
use of org.h2.tools.Recover in project h2database by h2database.
the class WebApp method tools.
private String tools() {
try {
String toolName = (String) attributes.get("tool");
session.put("tool", toolName);
String args = (String) attributes.get("args");
String[] argList = StringUtils.arraySplit(args, ',', false);
Tool tool = null;
if ("Backup".equals(toolName)) {
tool = new Backup();
} else if ("Restore".equals(toolName)) {
tool = new Restore();
} else if ("Recover".equals(toolName)) {
tool = new Recover();
} else if ("DeleteDbFiles".equals(toolName)) {
tool = new DeleteDbFiles();
} else if ("ChangeFileEncryption".equals(toolName)) {
tool = new ChangeFileEncryption();
} else if ("Script".equals(toolName)) {
tool = new Script();
} else if ("RunScript".equals(toolName)) {
tool = new RunScript();
} else if ("ConvertTraceFile".equals(toolName)) {
tool = new ConvertTraceFile();
} else if ("CreateCluster".equals(toolName)) {
tool = new CreateCluster();
} else {
throw DbException.throwInternalError(toolName);
}
ByteArrayOutputStream outBuff = new ByteArrayOutputStream();
PrintStream out = new PrintStream(outBuff, false, "UTF-8");
tool.setOut(out);
try {
tool.runTool(argList);
out.flush();
String o = new String(outBuff.toByteArray(), StandardCharsets.UTF_8);
String result = PageParser.escapeHtml(o);
session.put("toolResult", result);
} catch (Exception e) {
session.put("toolResult", getStackTrace(0, e, true));
}
} catch (Exception e) {
server.traceError(e);
}
return "tools.jsp";
}
use of org.h2.tools.Recover in project h2database by h2database.
the class PageLog method recover.
/**
* Run one recovery stage. There are three recovery stages: 0: only the undo
* steps are run (restoring the state before the last checkpoint). 1: the
* pages that are used by the transaction log are allocated. 2: the
* committed operations are re-applied.
*
* @param stage the recovery stage
* @return whether the transaction log was empty
*/
boolean recover(int stage) {
if (trace.isDebugEnabled()) {
trace.debug("log recover stage: " + stage);
}
if (stage == RECOVERY_STAGE_ALLOCATE) {
PageInputStream in = new PageInputStream(store, logKey, firstTrunkPage, firstDataPage);
usedLogPages = in.allocateAllPages();
in.close();
return true;
}
PageInputStream pageIn = new PageInputStream(store, logKey, firstTrunkPage, firstDataPage);
DataReader in = new DataReader(pageIn);
int logId = 0;
Data data = store.createData();
boolean isEmpty = true;
try {
int pos = 0;
while (true) {
int x = in.readByte();
if (x < 0) {
break;
}
pos++;
isEmpty = false;
if (x == UNDO) {
int pageId = in.readVarInt();
int size = in.readVarInt();
if (size == 0) {
in.readFully(data.getBytes(), store.getPageSize());
} else if (size == 1) {
// empty
Arrays.fill(data.getBytes(), 0, store.getPageSize(), (byte) 0);
} else {
in.readFully(compressBuffer, size);
try {
compress.expand(compressBuffer, 0, size, data.getBytes(), 0, store.getPageSize());
} catch (ArrayIndexOutOfBoundsException e) {
DbException.convertToIOException(e);
}
}
if (stage == RECOVERY_STAGE_UNDO) {
if (!undo.get(pageId)) {
if (trace.isDebugEnabled()) {
trace.debug("log undo {0}", pageId);
}
store.writePage(pageId, data);
undo.set(pageId);
undoAll.set(pageId);
} else {
if (trace.isDebugEnabled()) {
trace.debug("log undo skip {0}", pageId);
}
}
}
} else if (x == ADD) {
int sessionId = in.readVarInt();
int tableId = in.readVarInt();
Row row = readRow(store.getDatabase().getRowFactory(), in, data);
if (stage == RECOVERY_STAGE_UNDO) {
store.allocateIfIndexRoot(pos, tableId, row);
} else if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) {
trace.debug("log redo + table: " + tableId + " s: " + sessionId + " " + row);
}
store.redo(tableId, row, true);
} else {
if (trace.isDebugEnabled()) {
trace.debug("log ignore s: " + sessionId + " + table: " + tableId + " " + row);
}
}
}
} else if (x == REMOVE) {
int sessionId = in.readVarInt();
int tableId = in.readVarInt();
long key = in.readVarLong();
if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) {
trace.debug("log redo - table: " + tableId + " s:" + sessionId + " key: " + key);
}
store.redoDelete(tableId, key);
} else {
if (trace.isDebugEnabled()) {
trace.debug("log ignore s: " + sessionId + " - table: " + tableId + " " + key);
}
}
}
} else if (x == TRUNCATE) {
int sessionId = in.readVarInt();
int tableId = in.readVarInt();
if (stage == RECOVERY_STAGE_REDO) {
if (isSessionCommitted(sessionId, logId, pos)) {
if (trace.isDebugEnabled()) {
trace.debug("log redo truncate table: " + tableId);
}
store.redoTruncate(tableId);
} else {
if (trace.isDebugEnabled()) {
trace.debug("log ignore s: " + sessionId + " truncate table: " + tableId);
}
}
}
} else if (x == PREPARE_COMMIT) {
int sessionId = in.readVarInt();
String transaction = in.readString();
if (trace.isDebugEnabled()) {
trace.debug("log prepare commit " + sessionId + " " + transaction + " pos: " + pos);
}
if (stage == RECOVERY_STAGE_UNDO) {
int page = pageIn.getDataPage();
setPrepareCommit(sessionId, page, transaction);
}
} else if (x == ROLLBACK) {
int sessionId = in.readVarInt();
if (trace.isDebugEnabled()) {
trace.debug("log rollback " + sessionId + " pos: " + pos);
}
// ignore - this entry is just informational
} else if (x == COMMIT) {
int sessionId = in.readVarInt();
if (trace.isDebugEnabled()) {
trace.debug("log commit " + sessionId + " pos: " + pos);
}
if (stage == RECOVERY_STAGE_UNDO) {
setLastCommitForSession(sessionId, logId, pos);
}
} else if (x == NOOP) {
// nothing to do
} else if (x == CHECKPOINT) {
logId++;
} else if (x == FREE_LOG) {
int count = in.readVarInt();
for (int i = 0; i < count; i++) {
int pageId = in.readVarInt();
if (stage == RECOVERY_STAGE_REDO) {
if (!usedLogPages.get(pageId)) {
store.free(pageId, false);
}
}
}
} else {
if (trace.isDebugEnabled()) {
trace.debug("log end");
break;
}
}
}
} catch (DbException e) {
if (e.getErrorCode() == ErrorCode.FILE_CORRUPTED_1) {
trace.debug("log recovery stopped");
} else {
throw e;
}
} catch (IOException e) {
trace.debug("log recovery completed");
}
undo = new BitSet();
if (stage == RECOVERY_STAGE_REDO) {
usedLogPages = null;
}
return isEmpty;
}
Aggregations