1. 程式人生 > 其它 >springboot -- 每天自動備份 mysql 資料

springboot -- 每天自動備份 mysql 資料

技術標籤:springboot資料(Mysql-redis等)備份mysql自動備份java資料備份

一、說明

使用技術: mysqldump mysql 自帶工具

mysqldump備份簡單操作:

  • mysqldump -h[ip] -P[埠號] -u[使用者名稱] -p[密碼] 資料庫名 表名 >匯出的檔名.sql

  • mysqldump -h[ip] -P[埠號] -u[使用者名稱] -p[密碼] 資料庫名 表名1 表名2 表名3 | gzip >匯出的檔名.sql.gz

gzip 為直接壓縮匯出,需安裝gzip 命令可使用
參考:https://blog.csdn.net/yuxisanno139/article/details/83016520

二、使用

  • win 開啟 cmd 執行命令,linux 直接使用
  • win 的cmd 執行需當前 pc需安裝 mysql
  • 伺服器 執行 需安裝mysql 或 單獨安裝 mysqldump 單獨安裝命令: yum -y install holland-mysqldump.noarch
  • win 和 cmd 的區別在最後的檔案儲存目錄, 注意更換
  • mysql8+版本 需要 --column-statistics=0 引數,mysql8- 版本請移除該引數
  • 出現 sql_mode=... 的錯誤看錯誤一處理方法

不壓縮備份

mysqldump --column-statistics=0 -u賬號 -p密碼 -h域名或ip -
P3306 --databases 資料庫名 > F:/sql/spring-boot-plus2.sql

壓縮備份 (增加 | gzip)
需安裝 gzip 命令, 參考:參考:https://blog.csdn.net/yuxisanno139/article/details/83016520

mysqldump --column-statistics=0  -u賬號 -p密碼 -h域名或ip -P3306 --databases 資料庫名  | gzip > F:/sql/spring-boot-plus2.gz

三、錯誤說明

錯誤1

錯誤資訊

mysqldump: [ERROR] unknown variable 'sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
.

處理方法:
開啟mysql 找到目錄: my.ini 檔案, 註釋 sql_mode=.... 的那一行資料

錯誤2

錯誤資訊:

 Couldn't execute 'SELECT COLUMN_NAME,                       JSON_EXTRACT(HISTOGRAM, '$. ..............

處理方法:

新增: --column-statistics=0

三、springboot 整合使用

該備份使用流, 獲取備份資料在寫入檔案,和直接使用命令有些小區別

本次沒有寫 sql檔案壓縮和自動刪除 n天前資料,可自行處理

注意:此程式碼無法使用命令壓縮,只能程式碼壓縮

package com.ws.ldy.task.sys;

import com.ws.ldy.common.utils.LocalDateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.*;


/**
 * MYSQL 資料自動備份
 * <P>
 *    請參考文章: https://blog.csdn.net/qq_41463655/article/details/112628365
 * </P>
 * @author wangsong
 * @date 2021/1/14 0014 19:12
 * @return
 * @version 1.0.0
 */
@Component
@Configuration
@EnableScheduling
@Slf4j
public class MysqlDataBackup {


    /**
     * 備份 sql 存放目錄(相對路徑, 注意可能需要在 MvcConfig 配置訪問許可權)
     */
    String filePath = "File/sql/";

    /**
     * 資料庫版本是否為 8.0 + (false=否  true=是), mysql8+ 需要引數  --column-statistics=0  , mysql8- 不需要
     */
    Boolean isDbVersion8 = false;

    /**
     * 備份命令
     * USERNAME   賬號
     * PASSWORD   密碼
     * SERVERPATH 伺服器IP/域名
     * DBNAME     資料庫名稱
     * FILEPATH   備份檔案存放地址+名稱
     * 說明
     * cmdCompression : 需壓縮 (本地或伺服器需安裝 mysqldump 命令(安裝mysql自帶患獨立安裝) +  gzip 命令(獨立安裝))
     * cmd :            不壓縮 (本地或伺服器需安裝 mysqldump 命令(安裝mysql自帶患獨立安裝)
     * --column-statistics=0     mysql8 新增該引數, 非mysql8 不新增, 否則將出錯
     */
    String cmdMysql8 = "mysqldump --column-statistics=0  -u{USERNAME} -p{PASSWORD} -h{SERVERPATH} -P3306 --databases {DBNAME}"; //  > {FILEPATH}.sql
    String cmd = "mysqldump  -u{USERNAME} -p{PASSWORD} -h{SERVERPATH} -P3306 --databases {DBNAME}";      //  > {FILEPATH}.sql


    @Value("${spring.datasource.dynamic.datasource.db1.url}")
    private String dbUrl;

    @Value("${spring.datasource.dynamic.datasource.db1.username}")
    private String dbUserName;

    @Value("${spring.datasource.dynamic.datasource.db1.password}")
    private String dbPassWord;


    /**
     * 每天凌晨4點 【  0 0 4 1/1 * ? 】
     * 測試 20 秒一次【  0/20 * * * * ? 】
     */
    @Scheduled(cron = "0 0 4 1/1 * ?")
    private void configureTasks() {
        log.info("【備份資料庫】--START");
        String dbUrl2 = dbUrl.replace("jdbc:mysql://", "");

        // 獲取資料庫名稱
        String dbName = dbUrl2.substring(dbUrl2.lastIndexOf("/") + 1, dbUrl2.indexOf("?"));
        // 獲取資料庫地址
        String serverPath = dbUrl2.substring(0, dbUrl2.lastIndexOf("/"));
        // 資料庫賬號
        String username = dbUserName;
        // 資料庫密碼
        String password = dbPassWord;

        // 備份檔案目錄+名稱  備份檔案存放目錄+名稱(名稱 = 資料庫名+時間字串.sql)
        String timeStr = LocalDateTimeUtil.convertLDTToStr(LocalDateTimeUtil.now())
                .replaceAll("-", "_")
                .replaceAll(" ", "_")
                .replaceAll(":", "");
        timeStr = timeStr.substring(0, 15);
        String pathFileName = filePath + dbName + "_" + timeStr + ".sql";
        String newCmd = "";
        if (isDbVersion8) {
            newCmd = cmdMysql8;
        } else {
            newCmd = cmd;
        }
        // 執行命令
        newCmd =  newCmd.replace("{USERNAME}", username)
                .replace("{PASSWORD}", password)
                .replace("{SERVERPATH}", serverPath)
                .replace("{DBNAME}", dbName)
                .replace("{FILEPATH}", pathFileName);
        System.out.println(newCmd);
        PrintWriter printWriter = null;
        BufferedReader bufferedReader = null;
        try {
            // 建立存放sql的檔案
            existsFile(new File(pathFileName));
            printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(pathFileName), "utf8"));
            Process process = null;
            String property = System.getProperty("os.name");
            System.out.println(property);
            if (property.indexOf("Linux") != -1) {
                // linux
                process = Runtime.getRuntime().exec(new String[]{"bash", "-c", newCmd});
            } else {
                // 本地win
                process = Runtime.getRuntime().exec(newCmd);
            }
            InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), "utf8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                printWriter.println(line);
            }
            // 此次會執行過長時間,直到備份完成
            printWriter.flush();
            printWriter.close();
            //0 表示執行緒正常終止。
            if (process.waitFor() == 0) {
                // 執行緒正常執行
                log.info("【備份資料庫】SUCCESS,SQL檔案:{}", pathFileName);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("【備份資料庫】FAILURE");
        } finally {
            try {
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (printWriter != null) {
                    printWriter.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        log.info("【備份資料庫】--END");
    }


    /**
     * 判斷檔案是否存在,不存在建立
     */
    private static void existsFile(File file) {
        // 判斷檔案路徑是否存在,不存在新建
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

備份目錄展示

win 在專案下
在這裡插入圖片描述
linux 將在專案部署根路徑下
在這裡插入圖片描述

  • 個人開源專案(通用後臺管理系統)–> https://gitee.com/wslxm/spring-boot-plus2 , 喜歡的可以看看

  • 本文到此結束,如果覺得有用,動動小手點贊或關注一下唄,將不定時持續更新更多的內容…,感謝大家的觀看!