Java實現Mysql數據庫自動備份


最近項目中有一個這樣的需求,要求定時備份數據庫。看了一些網上的資料,了解到主要思路是是使用java中的Runtime類的exec()方法,可以直接調用windows的cmd命令,參數就是Mysql的備份命令。

一、Runtime類

首先說說這個神奇的Runtime類,主要封裝了Java程序的運行環境,每一個Java程序都有一個與之對應的Runtime實例,應用程序通過該對象與運行時環境相連,應用程序不能創建自己的Runtime實例,但可以通過getRuntime()方法獲得與之關聯的Runtime對象。

Runtime代表Java程序的運行時環境,可以訪問JVM的相關信息,如處理器數量,內存信息。

1.1、常用API

     addShutdownHook(Thread hook)
      注冊新的虛擬機來關閉掛鈎。
    availableProcessors()
      向 Java 虛擬機返回可用處理器的數目。
    exec(String command)
      在單獨的進程中執行指定的字符串命令。
    exec(String[] cmdarray)
      在單獨的進程中執行指定命令和變量。
    exec(String[] cmdarray, String[] envp)
      在指定環境的獨立進程中執行指定命令和變量。
   exec(String[] cmdarray, String[] envp, File dir)
      在指定環境和工作目錄的獨立進程中執行指定的命令和變量。
    exec(String command, String[] envp)
      在指定環境的單獨進程中執行指定的字符串命令。
   exec(String command, String[] envp, File dir)
      在有指定環境和工作目錄的獨立進程中執行指定的字符串命令。
    exit(int status)
      通過啟動虛擬機的關閉序列,終止當前正在運行的 Java 虛擬機。
    freeMemory()
      返回 Java 虛擬機中的空閑內存量。
   gc()
      運行垃圾回收器。
    InputStream getLocalizedInputStream(InputStream in)
    已過時。 從 JDK 1.1 開始,將本地編碼字節流轉換為 Unicode 字符流的首選方法是使用 InputStreamReader 和 BufferedReader 類。
   OutputStream getLocalizedOutputStream(OutputStream out)
     已過時。 從 JDK 1.1 開始,將 Unicode 字符流轉換為本地編碼字節流的首選方法是使用 OutputStreamWriter、BufferedWriter 和 PrintWriter 類。
    getRuntime()
      返回與當前 Java 應用程序相關的運行時對象。
   halt(int status)
      強行終止目前正在運行的 Java 虛擬機。
    load(String filename)
      加載作為動態庫的指定文件名。
    loadLibrary(String libname)
      加載具有指定庫名的動態庫。
    maxMemory()
      返回 Java 虛擬機試圖使用的最大內存量。
    removeShutdownHook(Thread hook)
      取消注冊某個先前已注冊的虛擬機關閉掛鈎。
    runFinalization()
      運行掛起 finalization 的所有對象的終止方法。
    runFinalizersOnExit(value)
      已過時。 此方法本身具有不安全性。它可能對正在使用的對象調用終結方法,而其他線程正在操作這些對象,從而導致不正確的行為或死鎖。
    totalMemory()
      返回 Java 虛擬機中的內存總量。
   traceInstructions(on)
      啟用/禁用指令跟蹤。
    traceMethodCalls(on)
      啟用/禁用方法調用跟蹤。

1.2、使用exec(String cmd)方法備份數據庫

DatabaseTool

package com.china_amss.base.tools;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import com.china_amss.base.thread.ErrorStreamThread;

public class DatabaseTool {

    /**
     * 備份數據庫 ,控制台執行命令格式 "mysql的bin目錄/mysqldump --databases  -h主機ip -P端口  -u用戶名 -p密碼  --default-character-set=字符集  數據庫名 
     * @param mysqlPath mysql路徑
     * @param mysqlIp mysql主機ip
     * @param mysqlPort 端口
     * @param userName 用戶名
     * @param password 密碼
     * @param charset 字符集
     * @param database 數據庫名
     * @param resultFile 備份文件全路徑
     */
    public static void backup(String mysqlPath, String mysqlIp,    String mysqlPort, String userName, String password, String database, String resultFile) {
        InputStream in = null;
        InputStreamReader isr = null;
        BufferedReader br = null;
        FileOutputStream fout = null;
        OutputStreamWriter writer = null;
        try {
            Runtime rt = Runtime.getRuntime();
            // 調用mysql的安裝目錄的命令
            Process process = rt.exec("\"" + mysqlPath + File.separator + "mysqldump\" --databases -h" + mysqlIp 
             + " -P" +  mysqlPort + " -u" + userName + " -p" + password 
             + " --add-drop-database --default-character-set=utf8 "+ database + " --result-file="+resultFile);
            // 設置導出編碼為utf-8。這里必須是utf-8
            in = process.getInputStream();// 控制台的輸出信息作為輸入流
            ErrorStreamThread errStream = new ErrorStreamThread(process.getErrorStream()); //錯誤流另開線程,不然會阻塞
            errStream.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
        finally{
            try {
                if(writer != null){
                    writer.close();
                }
                if(fout != null){
                    fout.close();
                }
                if(br != null){
                    br.close();
                }
                if(isr != null){
                    isr.close();
                }
                if(in != null){
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

ErrorStreamThread類:

package com.china_amss.base.thread;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import com.china_amss.ktms.exception.KTMSException;

public class ErrorStreamThread extends Thread {

    private InputStream input; // 控制台errorStream

    public ErrorStreamThread(InputStream input) {
        this.input = input;
    }

    @Override
    public void run() {
        InputStreamReader isr = null;
        BufferedReader buff = null;

        try {
            isr = new InputStreamReader(input);
            buff = new BufferedReader(isr);
            String line;
            while ((line = buff.readLine()) != null) {
                if (line.indexOf("Warning") != 0) {
                    throw new Exception(line);
                }
            }
        } catch (Exception e) {
            throw new Exception("錯誤流線程方法異常", e);
        } finally {
            try {
                if (buff != null) {
                    buff.close();
                }
                if (isr != null) {
                    isr.close();
                }
            } catch (IOException e) {
                throw new Exception("錯誤流線程方法異常", e);
            }
        }
    }
}

注意:此處因為要輸出錯誤提示,所以要使用另外一條線程輸出,不然會阻塞

注意:上面用到的命令參數可以去查看我的另一篇專門整理了Mysql備份命令參數的文章,鏈接在這Mysql備份命令參數詳解


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM