提交 3f26a9ef authored 作者: Thomas Mueller's avatar Thomas Mueller

The Recover tool did not always work when the database contains referential integrity constraints.

上级 25d46b58
...@@ -1207,7 +1207,11 @@ public class Recover extends Tool implements DataHandler { ...@@ -1207,7 +1207,11 @@ public class Recover extends Tool implements DataHandler {
private void writeSchema(PrintWriter writer) { private void writeSchema(PrintWriter writer) {
MetaRecord.sort(schema); MetaRecord.sort(schema);
for (MetaRecord m : schema) { for (MetaRecord m : schema) {
writer.println(m.getSQL() + ";"); String sql = m.getSQL();
// create, but not referential integrity constraints and so on
if (sql.startsWith("CREATE ")) {
writer.println(sql + ";");
}
} }
for (Map.Entry<Integer, String> entry : tableMap.entrySet()) { for (Map.Entry<Integer, String> entry : tableMap.entrySet()) {
Integer objectId = entry.getKey(); Integer objectId = entry.getKey();
...@@ -1221,6 +1225,13 @@ public class Recover extends Tool implements DataHandler { ...@@ -1221,6 +1225,13 @@ public class Recover extends Tool implements DataHandler {
} }
writer.println("DROP ALIAS READ_CLOB;"); writer.println("DROP ALIAS READ_CLOB;");
writer.println("DROP ALIAS READ_BLOB;"); writer.println("DROP ALIAS READ_BLOB;");
for (MetaRecord m : schema) {
String sql = m.getSQL();
// everything except create
if (!sql.startsWith("CREATE ")) {
writer.println(sql + ";");
}
}
} }
private void createTemporaryTable(PrintWriter writer) { private void createTemporaryTable(PrintWriter writer) {
......
...@@ -7,12 +7,11 @@ ...@@ -7,12 +7,11 @@
package org.h2.test.unit; package org.h2.test.unit;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.tools.DeleteDbFiles; import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Recover;
/** /**
* Tests database recovery. * Tests database recovery.
...@@ -31,24 +30,22 @@ public class TestRecovery extends TestBase { ...@@ -31,24 +30,22 @@ public class TestRecovery extends TestBase {
public void test() throws SQLException { public void test() throws SQLException {
DeleteDbFiles.execute(baseDir, "recovery", true); DeleteDbFiles.execute(baseDir, "recovery", true);
org.h2.Driver.load(); org.h2.Driver.load();
String url = "jdbc:h2:" + baseDir + "/recovery;write_delay=0"; Connection conn = getConnection("recovery");
Connection conn1 = DriverManager.getConnection(url, "sa", "sa"); Statement stat = conn.createStatement();
Statement stat1 = conn1.createStatement(); stat.execute("create table test as select * from system_range(1, 100)");
Connection conn2 = DriverManager.getConnection(url, "sa", "sa"); stat.execute("create table a(id int primary key) as select * from system_range(1, 100)");
Statement stat2 = conn2.createStatement(); stat.execute("create table b(id int references a(id)) as select * from system_range(1, 100)");
stat1.execute("create table test as select * from system_range(1, 100)"); stat.execute("alter table a add foreign key(id) references b(id)");
stat1.execute("create table abc(id int)");
conn2.setAutoCommit(false);
// this is not committed
// recovery might try to roll back this
stat2.execute("delete from test");
// overwrite the data of test
stat1.execute("insert into abc select * from system_range(1, 100)");
stat1.execute("shutdown immediately");
// Recover.execute("data", null);
Connection conn = DriverManager.getConnection(url, "sa", "sa");
conn.close(); conn.close();
Recover.execute(baseDir, "recovery");
DeleteDbFiles.execute(baseDir, "recovery", true); DeleteDbFiles.execute(baseDir, "recovery", true);
conn = getConnection("recovery", "diff", "");
stat = conn.createStatement();
stat.execute("runscript from '" + baseDir + "/recovery.data.sql'");
stat.execute("select * from test");
conn.close();
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论