提交 ea636aad authored 作者: Thomas Mueller's avatar Thomas Mueller

The CreateCluster tool now sets the source database in exclusive mode before…

The CreateCluster tool now sets the source database in exclusive mode before copying data to the new database.
上级 094e1847
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
*/ */
package org.h2.tools; package org.h2.tools;
import java.io.OutputStream;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -94,17 +95,17 @@ public class CreateCluster extends Tool { ...@@ -94,17 +95,17 @@ public class CreateCluster extends Tool {
} }
private void process(String urlSource, String urlTarget, String user, String password, String serverList) throws SQLException { private void process(String urlSource, String urlTarget, String user, String password, String serverList) throws SQLException {
Connection conn = null; Connection connSource = null, connTarget = null;
Statement stat = null; Statement statSource = null, statTarget = null;
String scriptFile = "backup.sql";
try { try {
org.h2.Driver.load(); org.h2.Driver.load();
// use cluster='' so connecting is possible even if the cluster is enabled
conn = DriverManager.getConnection(urlSource + ";CLUSTER=''", user, password); // verify that the database doesn't exist
conn.close();
boolean exists; boolean exists;
try { try {
conn = DriverManager.getConnection(urlTarget + ";IFEXISTS=TRUE", user, password); connTarget = DriverManager.getConnection(urlTarget + ";IFEXISTS=TRUE", user, password);
conn.close(); connTarget.close();
exists = true; exists = true;
} catch (SQLException e) { } catch (SQLException e) {
// database does not exists - ok // database does not exists - ok
...@@ -114,31 +115,45 @@ public class CreateCluster extends Tool { ...@@ -114,31 +115,45 @@ public class CreateCluster extends Tool {
throw new SQLException("Target database must not yet exist. Please delete it first"); throw new SQLException("Target database must not yet exist. Please delete it first");
} }
// TODO cluster: need to open the database in exclusive mode, // use cluster='' so connecting is possible
// so that other applications // even if the cluster is enabled
// cannot change the data while it is restoring the second database. connSource = DriverManager.getConnection(urlSource + ";CLUSTER=''", user, password);
// But there is currently no exclusive mode. statSource = connSource.createStatement();
String scriptFile = "backup.sql"; // enable the exclusive mode, so that other applications
Script sc = new Script(); // cannot change the data while it is restoring the second database
sc.setOut(out); statSource.execute("SET EXCLUSIVE TRUE");
sc.process(urlSource, user, password, scriptFile);
RunScript runscript = new RunScript(); // backup
runscript.setOut(out); Script script = new Script();
runscript.process(urlTarget, user, password, scriptFile, null, false); script.setOut(out);
IOUtils.delete(scriptFile); OutputStream scriptOut = null;
try {
scriptOut = IOUtils.openFileOutputStream(scriptFile, false);
script.process(connSource, scriptOut);
} finally {
IOUtils.closeSilently(scriptOut);
}
// restore
RunScript runScript = new RunScript();
runScript.setOut(out);
runScript.process(urlTarget, user, password, scriptFile, null, false);
connTarget = DriverManager.getConnection(urlTarget, user, password);
statTarget = connTarget.createStatement();
// set the cluster to the serverList on both databases // set the cluster to the serverList on both databases
conn = DriverManager.getConnection(urlSource, user, password); statSource.executeUpdate("SET CLUSTER '" + serverList + "'");
stat = conn.createStatement(); statTarget.executeUpdate("SET CLUSTER '" + serverList + "'");
stat.executeUpdate("SET CLUSTER '" + serverList + "'");
conn.close(); statSource.execute("SET EXCLUSIVE FALSE");
conn = DriverManager.getConnection(urlTarget, user, password);
stat = conn.createStatement();
stat.executeUpdate("SET CLUSTER '" + serverList + "'");
} finally { } finally {
JdbcUtils.closeSilently(conn); IOUtils.delete(scriptFile);
JdbcUtils.closeSilently(stat); JdbcUtils.closeSilently(statSource);
JdbcUtils.closeSilently(statTarget);
JdbcUtils.closeSilently(connSource);
JdbcUtils.closeSilently(connTarget);
} }
} }
......
...@@ -168,10 +168,25 @@ public class Script extends Tool { ...@@ -168,10 +168,25 @@ public class Script extends Tool {
*/ */
void process(String url, String user, String password, OutputStream o) throws SQLException { void process(String url, String user, String password, OutputStream o) throws SQLException {
Connection conn = null; Connection conn = null;
Statement stat = null;
try { try {
org.h2.Driver.load(); org.h2.Driver.load();
conn = DriverManager.getConnection(url, user, password); conn = DriverManager.getConnection(url, user, password);
process(conn, o);
} finally {
JdbcUtils.closeSilently(conn);
}
}
/**
* Backs up a database to a stream. The stream is not closed.
* The connection is not closed.
*
* @param conn the connection
* @param o the output stream
*/
void process(Connection conn, OutputStream o) throws SQLException {
Statement stat = null;
try {
stat = conn.createStatement(); stat = conn.createStatement();
PrintWriter writer = new PrintWriter(IOUtils.getWriter(o)); PrintWriter writer = new PrintWriter(IOUtils.getWriter(o));
ResultSet rs = stat.executeQuery("SCRIPT"); ResultSet rs = stat.executeQuery("SCRIPT");
...@@ -182,7 +197,6 @@ public class Script extends Tool { ...@@ -182,7 +197,6 @@ public class Script extends Tool {
writer.flush(); writer.flush();
} finally { } finally {
JdbcUtils.closeSilently(stat); JdbcUtils.closeSilently(stat);
JdbcUtils.closeSilently(conn);
} }
} }
......
...@@ -589,6 +589,7 @@ public class TestTools extends TestBase { ...@@ -589,6 +589,7 @@ public class TestTools extends TestBase {
assertTrue(rs.next()); assertTrue(rs.next());
assertFalse(rs.next()); assertFalse(rs.next());
try { try {
// must fail when the database is in use
Backup.main("-file", fileName, "-dir", baseDir, "-db", "utils"); Backup.main("-file", fileName, "-dir", baseDir, "-db", "utils");
fail(); fail();
} catch (SQLException e) { } catch (SQLException e) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论