springboot -- 每天自動備份 mysql 資料
阿新 • • 發佈:2021-02-06
技術標籤: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 , 喜歡的可以看看
-
本文到此結束,如果覺得有用,動動小手點贊或關注一下唄,將不定時持續更新更多的內容…,感謝大家的觀看!