利用 Java Runtime.exec() 調用系統原生 mysqldump 工具,通過管道流捕獲輸出並寫入文件。相比 JDBC 逐行查詢,mysqldump 具備並行導出、鎖控制、一致性快照等原生優勢,性能強數量級。
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
public class MySQLBackupUtil {
/**
* 執行備份
* @param hostIP 數據庫主機 IP
* @param userName 用戶名
* @param password 密碼(注意命令行洩露風險,生產建議用 --defaults-extra-file)
* @param savePath 備份文件目錄
* @param fileName 備份文件名(建議含時間戳)
* @param databaseName 目標數據庫
* @return 成功返回 true
*/
public static boolean exportDatabase(String hostIP, String userName, String password,
String savePath, String fileName, String databaseName) {
File dir = new File(savePath);
if (!dir.exists()) dir.mkdirs();
if (!savePath.endsWith(File.separator)) savePath += File.separator;
String dumpCmd = String.format("mysqldump -h%s -u%s -p%s --single-transaction --routines --triggers --events --set-gtid-purged=OFF --default-character-set=utf8mb4 %s",
hostIP, userName, password, databaseName);
Process process = null;
try (PrintWriter writer = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(savePath + fileName), "utf-8"), true)) {
process = Runtime.getRuntime().exec(dumpCmd);
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream(), "utf-8"))) {
String line;
while ((line = reader.readLine()) != null) {
writer.println(line);
}
}
int exitCode = process.waitFor();
return exitCode == 0;
} catch (IOException | InterruptedException e) {
e.printStackTrace();
return false;
} finally {
if (process != null) process.destroy();
}
}
public static void main(String[] args) {
String timestamp = new java.text.SimpleDateFormat("yyyyMMdd_HHmmss").format(new java.util.Date());
boolean ok = exportDatabase("172.16.0.127", "root", "123456",
"D:/backupDatabase", "backup_" + timestamp + ".sql", "test");
System.out.println(ok ? "數據庫備份成功!" : "數據庫備份失敗!");
}
}
| 參數 | 作用 |
|---|---|
--single-transaction | InnoDB 熱備份核心,啟動一致性快照,無需全局鎖 |
--routines --triggers --events | 導出存儲過程、觸發器、事件調度器 |
--set-gtid-purged=OFF | 避免 GTID 導入衝突,跨實例還原更安全 |
--default-character-set=utf8mb4 | 強制字符集,防止 Emoji 亂碼 |
--master-data=2 | (可選)在輸出中記錄 Binlog 位點,便於搭建從庫 |
~/.my.cnf 或 --defaults-extra-file=/etc/mysql/backup.cnf,內容:
[mysqldump] user=backup_user password=strong_random_password host=127.0.0.1調用時
mysqldump --defaults-extra-file=...,避免 ps -ef 洩露。
gzip:mysqldump ... | gzip > backup.sql.gz,節省 70%+ 空間。
CHECKSUM TABLE 或解析 SQL 統計行數,對比源庫。
Access denied:檢查用戶是否具備 SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER 權限。Got error: 1016: Can't open file:可能是表損壞或權限問題,先 CHECK TABLE。SHOW PROCESSLIST 確認無 Waiting for table metadata lock。--quick(默認開啟)。Spring Boot 中可用 @Scheduled(cron = "0 0 2 * * ?") 每天凌晨 2 點執行;或接入 XXL-JOB、Elastic-Job 實現分佈式調度、失敗重試、告警通知。
掌握此方案,即可構建企業級、可監控、可擴展的 MySQL 備份體系。