|
|
@ -5,35 +5,83 @@ import com.dsideal.YunXiaoTools.Utils.MultiThreadDownloader;
|
|
|
|
import com.jfinal.kit.PropKit;
|
|
|
|
import com.jfinal.kit.PropKit;
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
import java.io.*;
|
|
|
|
|
|
|
|
import java.sql.Connection;
|
|
|
|
|
|
|
|
import java.sql.DriverManager;
|
|
|
|
|
|
|
|
import java.sql.SQLException;
|
|
|
|
|
|
|
|
import java.sql.Statement;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.zip.*;
|
|
|
|
import java.util.zip.*;
|
|
|
|
|
|
|
|
|
|
|
|
public class MysqlRestoreService {
|
|
|
|
public class MysqlRestoreService {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final String jdbcUrl;
|
|
|
|
|
|
|
|
private final String username;
|
|
|
|
|
|
|
|
private final String password;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public MysqlRestoreService() {
|
|
|
|
|
|
|
|
jdbcUrl = PropKit.get("write.jdbcUrl");
|
|
|
|
|
|
|
|
username = PropKit.get("write.user");
|
|
|
|
|
|
|
|
password = PropKit.get("write.password");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 执行完整的还原流程
|
|
|
|
* 执行完整的还原流程
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* @param obsKey OBS上的文件路径
|
|
|
|
* @param obsKey OBS上的文件路径
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public void restore(String obsKey) {
|
|
|
|
public void restore(String jdbcUrl, String username, String password, String obsKey) {
|
|
|
|
String tempDir = System.getProperty("java.io.tmpdir");
|
|
|
|
String tempDir = System.getProperty("java.io.tmpdir");
|
|
|
|
String sqlFile = null;
|
|
|
|
String sqlFile = null;
|
|
|
|
String zipFile = tempDir + obsKey.split("/")[2];
|
|
|
|
String zipFile = tempDir + obsKey.split("/")[2];
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
// 1. 从OBS下载ZIP文件
|
|
|
|
// 1. 从OBS下载ZIP文件
|
|
|
|
downloadFromObs(obsKey, tempDir);
|
|
|
|
downloadFromObs(obsKey, tempDir);
|
|
|
|
|
|
|
|
|
|
|
|
System.out.println("文件下载完成: " + zipFile);
|
|
|
|
System.out.println("文件下载完成: " + zipFile);
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 解压ZIP文件
|
|
|
|
// 2. 解压ZIP文件
|
|
|
|
sqlFile = unzipFile(zipFile);
|
|
|
|
sqlFile = unzipFile(zipFile);
|
|
|
|
System.out.println("文件解压完成: " + sqlFile);
|
|
|
|
System.out.println("文件解压完成: " + sqlFile);
|
|
|
|
|
|
|
|
|
|
|
|
// 3. 还原数据库
|
|
|
|
// 3. 还原数据库
|
|
|
|
DatabaseRestorer dr=new DatabaseRestorer(PropKit.get("write.jdbcUrl"), PropKit.get("write.user"), PropKit.get("write.password"));
|
|
|
|
try {
|
|
|
|
dr.restore(sqlFile);
|
|
|
|
// 读取SQL文件内容
|
|
|
|
System.out.println("数据库还原完成");
|
|
|
|
List<String> sqlStatements = parseSqlFile(sqlFile);
|
|
|
|
|
|
|
|
System.out.println("SQL文件解析完成,共 " + sqlStatements.size() + " 条语句");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 执行SQL语句
|
|
|
|
|
|
|
|
try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
|
|
|
|
|
|
|
|
conn.setAutoCommit(false); // 开启事务
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try (Statement stmt = conn.createStatement()) {
|
|
|
|
|
|
|
|
int total = sqlStatements.size();
|
|
|
|
|
|
|
|
int current = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (String sql : sqlStatements) {
|
|
|
|
|
|
|
|
if (!sql.trim().isEmpty()) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
stmt.execute(sql);
|
|
|
|
|
|
|
|
current++;
|
|
|
|
|
|
|
|
// 显示进度
|
|
|
|
|
|
|
|
if (current % 100 == 0 || current == total) {
|
|
|
|
|
|
|
|
System.out.printf("\r还原进度: %.2f%% (%d/%d)", (current * 100.0 / total), current, total);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
|
|
|
System.err.println("\n执行SQL出错: " + sql);
|
|
|
|
|
|
|
|
System.err.println("错误信息: " + e.getMessage());
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
conn.commit(); // 提交事务
|
|
|
|
|
|
|
|
System.out.println("\n数据库还原完成");
|
|
|
|
|
|
|
|
} catch (SQLException e) {
|
|
|
|
|
|
|
|
conn.rollback(); // 发生错误时回滚
|
|
|
|
|
|
|
|
throw e;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
throw new RuntimeException("还原数据库失败: " + e.getMessage(), e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
System.out.println("数据库还原完成");
|
|
|
|
} catch (Exception e) {
|
|
|
|
} catch (Exception e) {
|
|
|
|
throw new RuntimeException("还原过程失败: " + e.getMessage(), e);
|
|
|
|
throw new RuntimeException("还原过程失败: " + e.getMessage(), e);
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
@ -100,12 +148,51 @@ public class MysqlRestoreService {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 解析SQL文件
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private List<String> parseSqlFile(String sqlFile) throws IOException {
|
|
|
|
|
|
|
|
List<String> sqlStatements = new ArrayList<>();
|
|
|
|
|
|
|
|
StringBuilder statement = new StringBuilder();
|
|
|
|
|
|
|
|
boolean inString = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try (BufferedReader reader = new BufferedReader(new FileReader(sqlFile))) {
|
|
|
|
|
|
|
|
String line;
|
|
|
|
|
|
|
|
while ((line = reader.readLine()) != null) {
|
|
|
|
|
|
|
|
// 跳过注释行
|
|
|
|
|
|
|
|
if (line.trim().startsWith("--") || line.trim().startsWith("/*")) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < line.length(); i++) {
|
|
|
|
|
|
|
|
char c = line.charAt(i);
|
|
|
|
|
|
|
|
// 处理字符串
|
|
|
|
|
|
|
|
if (c == '\'') {
|
|
|
|
|
|
|
|
inString = !inString;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
statement.append(c);
|
|
|
|
|
|
|
|
// 如果遇到分号且不在字符串中,说明一条语句结束
|
|
|
|
|
|
|
|
if (c == ';' && !inString) {
|
|
|
|
|
|
|
|
sqlStatements.add(statement.toString());
|
|
|
|
|
|
|
|
statement = new StringBuilder();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
statement.append("\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// 处理最后一条可能没有分号的语句
|
|
|
|
|
|
|
|
if (!statement.isEmpty()) {
|
|
|
|
|
|
|
|
sqlStatements.add(statement.toString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return sqlStatements;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
public static void main(String[] args) {
|
|
|
|
PropKit.use("application.properties");
|
|
|
|
PropKit.use("application.properties");
|
|
|
|
//获取最后一次上传的数据库文件
|
|
|
|
//获取最后一次上传的数据库文件
|
|
|
|
String key = CommonUtil.getLastDataBaseZip();
|
|
|
|
String key = CommonUtil.getLastDataBaseZip();
|
|
|
|
//开始还原数据库
|
|
|
|
|
|
|
|
MysqlRestoreService mysqlRestoreUtil = new MysqlRestoreService();
|
|
|
|
//还原数据库
|
|
|
|
mysqlRestoreUtil.restore(key);
|
|
|
|
MysqlRestoreService mr = new MysqlRestoreService();
|
|
|
|
|
|
|
|
mr.restore(mr.jdbcUrl, mr.username, mr.password, key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|