main
黄海 7 months ago
parent 1b51d00f09
commit ed7b56ccfc

@ -7,6 +7,9 @@ import com.obs.services.ObsClient;
import java.io.*; import java.io.*;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.zip.*; import java.util.zip.*;
public class MysqlRestoreService { public class MysqlRestoreService {
@ -116,58 +119,80 @@ public class MysqlRestoreService {
return extractedFile; return extractedFile;
} }
/**
*
*/
private void restoreDatabase(String sqlFile) { private void restoreDatabase(String sqlFile) {
try { try {
// 获取mysql命令路径
String mysqlPath = CommonUtil.getMySQLPath(); String mysqlPath = CommonUtil.getMySQLPath();
// 构建还原命令
ProcessBuilder pb = new ProcessBuilder( ProcessBuilder pb = new ProcessBuilder(
mysqlPath, mysqlPath,
"-h" + dbHost, "-h" + dbHost,
"-P" + dbPort, "-P" + dbPort,
"-u" + dbUser, "-u" + dbUser,
//"--ssl-mode=DISABLED", "--skip-ssl",
"--skip-ssl", // 替换为MariaDB兼容的参数
dbName dbName
); );
// 设置环境变量传递密码
pb.environment().put("MYSQL_PWD", dbPassword); pb.environment().put("MYSQL_PWD", dbPassword);
// 启动进程
// 执行还原命令
Process process = pb.start(); Process process = pb.start();
// 使用多线程处理输入输出流,避免死锁
ExecutorService executor = Executors.newFixedThreadPool(2);
// 处理错误输出流
Future<?> errorFuture = executor.submit(() -> {
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getErrorStream()))) {
String line;
while ((line = reader.readLine()) != null) {
if (!line.contains("WARNING")) {
System.out.println("还原进度: " + line);
}
}
} catch (IOException e) {
e.printStackTrace();
}
});
// 将SQL文件内容写入mysql进程的输入流 // 处理输入流SQL文件
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sqlFile)); Future<?> inputFuture = executor.submit(() -> {
BufferedOutputStream bos = new BufferedOutputStream(process.getOutputStream())) { try (BufferedInputStream sqlInput = new BufferedInputStream(new FileInputStream(sqlFile));
BufferedOutputStream processOutput = new BufferedOutputStream(process.getOutputStream())) {
byte[] buffer = new byte[8192]; byte[] buffer = new byte[8192];
int len; int len;
while ((len = bis.read(buffer)) > 0) { long total = 0;
bos.write(buffer, 0, len); long fileSize = new File(sqlFile).length();
}
} while ((len = sqlInput.read(buffer)) != -1) {
// 读取错误输出 processOutput.write(buffer, 0, len);
StringBuilder errorOutput = new StringBuilder(); total += len;
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getErrorStream()))) { // 显示进度
String line; int progress = (int) ((total * 100) / fileSize);
while ((line = reader.readLine()) != null) { System.out.printf("\r导入进度: %d%%", progress);
if (!line.contains("WARNING")) {
errorOutput.append(line).append("\n");
System.out.println("还原进度: " + line);
} }
// 重要:刷新并关闭输出流
processOutput.flush();
processOutput.close();
} catch (IOException e) {
e.printStackTrace();
} }
});
// 等待输入输出处理完成
try {
inputFuture.get();
errorFuture.get();
} catch (Exception e) {
throw new RuntimeException("处理输入输出流失败", e);
} finally {
executor.shutdown();
} }
// 等待命令执行完成
// 等待进程完成
int exitCode = process.waitFor(); int exitCode = process.waitFor();
if (exitCode != 0) { if (exitCode != 0) {
throw new RuntimeException("数据库还原失败:\n" + errorOutput); throw new RuntimeException("数据库还原失败,退出码: " + exitCode);
} }
System.out.println("\n数据库还原完成");
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("还原数据库失败: " + e.getMessage(), e); throw new RuntimeException("还原数据库失败: " + e.getMessage(), e);
} }

Loading…
Cancel
Save