main
黄海 6 months ago
parent 1b51d00f09
commit ed7b56ccfc

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

Loading…
Cancel
Save