首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

Java 實現 MySQL 數據庫備份:基於 mysqldump 的生產級方案

     編輯:MySQL 綜合教學

核心思路

利用 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-transactionInnoDB 熱備份核心,啟動一致性快照,無需全局鎖
--routines --triggers --events導出存儲過程、觸發器、事件調度器
--set-gtid-purged=OFF避免 GTID 導入衝突,跨實例還原更安全
--default-character-set=utf8mb4強制字符集,防止 Emoji 亂碼
--master-data=2(可選)在輸出中記錄 Binlog 位點,便於搭建從庫

生產環境安全增強

  1. 密碼不入命令行:建立 ~/.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 洩露。
  2. 壓縮存儲:管道接 gzip:mysqldump ... | gzip > backup.sql.gz,節省 70%+ 空間。
  3. 異步上傳:備份完成後異步上傳至 S3/OSS/HDFS,實現異地災備。
  4. 校驗機制:導出後執行 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。
  • 文件過大導致 OOM:Java 端使用流式寫入(如代碼所示),不載入內存;若 mysqldump 端內存不足,加 --quick(默認開啟)。

擴展:定時任務集成

Spring Boot 中可用 @Scheduled(cron = "0 0 2 * * ?") 每天凌晨 2 點執行;或接入 XXL-JOB、Elastic-Job 實現分佈式調度、失敗重試、告警通知。

掌握此方案,即可構建企業級、可監控、可擴展的 MySQL 備份體系。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved