SpringBoot 項目中 對Mysql ,MongoDB 數據庫進行備份恢復操作
版本說明 本次項目 mysql版本爲5.7.29 mongo版本爲4.2.5
(一) 原生的數據庫備份命令
mysql
# 備份命令
mysqldump -hIp地址 -u用戶名 -p密碼 需備份的數據庫 > 備份地址
#恢復命令
mysql -hIp地址 -u用戶名 -p密碼 需還原的數據庫 < 備份sql文件位置
mongodb
mongo 備份 與mysql 不同 mysql 會默認將一個庫中的所有表 備份在一個sql文件中 ,而mongo備份則會根據你選擇備份的數據庫名生成一個文件夾
文件夾中存放 庫中所有的文檔表 後綴爲.bson
# 備份命令 Mongo庫無密碼時
mongodump -h Ip:端口 備份數據庫名 -o 備份文件夾位置
# 備份命令 Mongo庫有密碼時
mongodump -d 備份數據庫名 -o 備份文件夾位置 -hIP-u用戶名 -p密碼 --authenticationDatabase admin
#恢復命令 Mongo庫無密碼時
mongorestore -h Ip:端口 -d 恢復數據庫名 --dir 要恢復的文件夾位置
#恢復命令 Mongo庫有密碼時
mongorestore -d 恢復數據庫名 --dir 要恢復的文件夾位置 -hIp -u用戶名 -p密碼 --authenticationDatabase admin
java 項目中對Mongo mysql 等數據庫備份其實主要使用了 java.lang.Runtime 這個類
Runtime 類的高級用法就自行百度吧 哈哈
下邊開始我們的實踐操作
(二)java 代碼實現
首先貼上我的自定義的常量 包含了 要備份的mysql mongo的Ip 賬戶密碼, 備份路徑等信息
/** 需備份恢復MysqlIP */
public static String MONGO_HOST_PORT = GlobalUtil.Ip+":27017";
/** 需要備份的Mongo數據庫名 */
public static String[] MONGO_DATA_BASE = {"庫1", "庫2", "庫3"};
/** Mongo備份文件 路徑 分win路徑和linux 路徑*/
// public static String MONGO_FILE_PATH = "d:\\cattleDatabase\\mongo\\";
public static String MONGO_FILE_PATH = "/webtest/dataBase/mongo/";
// -------------------------------------------------------------
/** 需備份恢復MysqlIP */
public static String HOST_PORT = GlobalUtil.Ip;
/** 需要備份的Mysql數據庫名 */
public static String DATA_BASE = "cattle-vue";
/** MYsql備份文件 路徑 分win路徑和linux 路徑 */
public static String FILE_PATH = "/webtest/dataBase/mysql/";
// public static String FILE_PATH = "d:\\cattleDatabase\\mysql\\";
/** 操控IP 備份 停服 指定隨機等 */
public static final String Ip = "xxxxxxx";
/** 操作mongo賬戶 */
public static final String MONGO_USER_NAME = "xxx";
/** 操作mongo密碼 */
public static final String MONGO_PASS_WORD = "xxxx";
/** 操作mysql賬戶 */
public static final String USER_NAME = "xxx";
/** 操作mysql密碼 */
public static final String PASS_WORD = "xxxxxx";
首先需要注意的點 備份文件路徑 分linux 系統路徑 和我用的Win路徑 當然 在兩種操作系統上 命令行打開以及使用的方式也是不同的
linux 上
String[] command = {"/bin/sh", "-c", stmt};
win上
String[] command = {"cmd", "/c", stmt};
stmt 爲我們在控制檯執行的操作命令 exmaple: mysqldump -h 192.168.10.120 xxxxxxx
下方的 dumpService 是我爲了將 備份恢復記錄保存到數據庫中的 保存服務類接口
Mysql
一. 備份
/**
* Mysql 數據備份
*
* @return
*/
public AjaxResult dumpMysql() {
log.info("當前數據庫備份時間:{}", DateUtil.now());
// 獲取Runtime實例
Runtime runtime = Runtime.getRuntime();
String mysqlFileName=DATA_BASE + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss") + ".sql";
// 執行CMD命令
String stmt =
"mysqldump "
+ "-h "
+ HOST_PORT
+ " -u "
+ GlobalUtil.USER_NAME
+ " -p"
+ GlobalUtil.PASS_WORD
+ " "
+ DATA_BASE
+ " > "
+ FILE_PATH
+ mysqlFileName;
log.info("數據庫備份命令爲:{}", stmt);
if (!FileUtil.exist(FILE_PATH)) {
FileUtil.mkdir(FILE_PATH);
}
try {
// String[] command = {"cmd", "/c", stmt};
String[] command = {"/bin/sh", "-c", stmt};
Process process = runtime.exec(command);
InputStream input = process.getInputStream();
System.out.println(IOUtils.toString(input, "UTF-8"));
// 若有錯誤或者警告信息則輸出
InputStream errorStream = process.getErrorStream();
System.out.println(IOUtils.toString(errorStream, "gbk"));
if (input != null) {
input.close();
if (errorStream != null) {
errorStream.close();
}
}
if (process.waitFor() == 0) {
log.info("Mysql 數據庫備份成功,備份文件名:{}", mysqlFileName);
dumpService.insertDump(new Dump(SecurityUtils.getUsername(),HOST_PORT+":3306",mysqlFileName,"Mysql備份",FILE_PATH, new DateTime()));
return AjaxResult.success("數據庫備份成功,備份文件所在地:" + FILE_PATH + mysqlFileName);
} else {
return AjaxResult.error("網絡異常 數據庫備份失敗");
}
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("網絡異常");
}
}
二. 恢復
/**
* mysql 數據恢復
*
* @param fileName
* @return
*/
public AjaxResult restoreMysql(String fileName) {
try {
Runtime runtime = Runtime.getRuntime();
String realFilePath = FILE_PATH + fileName;
String cmd =
"mysql -h "
+ HOST_PORT
+ " -u"
+ GlobalUtil.USER_NAME
+ " -p"
+ GlobalUtil.PASS_WORD
+ " "
+ DATA_BASE
+ " < "
+ realFilePath;
// String[] command = {"cmd", "/c", cmd};
String[] command = {"/bin/sh", "-c", cmd};
Process process = runtime.exec(command);
OutputStream outputStream = process.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "utf-8");
writer.flush();
outputStream.close();
writer.close();
if (process.waitFor() == 0) {
dumpService.insertDump(
new Dump(
SecurityUtils.getUsername(),
HOST_PORT + ":3306",
fileName,
"Mysql恢復",
realFilePath,
new DateTime()));
return AjaxResult.success("還原的備份文件" + DumpDatabaseUtil.FILE_PATH + fileName + "成功");
} else {
return AjaxResult.error("網絡異常 數據庫備份失敗");
}
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("網絡異常 數據庫備份失敗");
}
}
Mongo
一. 備份
/**
*
* mongo 庫備份
*
* @return
*/
public AjaxResult dumpMongo() {
Runtime runtime = Runtime.getRuntime();
String MongoFileName="mongo" + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss");
try {
for (String database : MONGO_DATA_BASE) {
String stmt =
"mongodump "
+ " -d "
+ database
+ " -o "
+ MONGO_FILE_PATH
+ MongoFileName
+"/"
+ " -h "
+ MONGO_HOST_PORT
+" -u"+GlobalUtil.MONGO_USER_NAME
+" -p"+GlobalUtil.MONGO_PASS_WORD
+" --authenticationDatabase admin";
//-----------------------------------------
// "mongodump "
// + " -h "
// + MONGO_HOST_PORT
// + " -d "
// + database
// + " -o "
// + MONGO_FILE_PATH
// + MongoFileName
// +"/";
log.info("Mongo數據庫備份命令爲:{}", stmt);
if (!FileUtil.exist(MONGO_FILE_PATH)) {
FileUtil.mkdir(MONGO_FILE_PATH);
}
String[] command = {"/bin/sh", "-c", stmt};
// String[] command = {"cmd", "/c", stmt};
Process process = runtime.exec(command);
InputStream input = process.getInputStream();
System.out.println(IOUtils.toString(input, "UTF-8"));
// 若有錯誤或者警告信息則輸出
InputStream errorStream = process.getErrorStream();
System.out.println(IOUtils.toString(errorStream, "gbk"));
if (input != null) {
input.close();
if (errorStream != null) {
errorStream.close();
}
}
}
dumpService.insertDump(
new Dump(
SecurityUtils.getUsername(),
MONGO_HOST_PORT,
MongoFileName,
"Mongo備份",
MONGO_FILE_PATH + MongoFileName,
new DateTime()));
return AjaxResult.success("Mongo數據備份成功");
} catch (IOException e) {
e.printStackTrace();
return AjaxResult.error("Mongo 數據備份失敗");
}
}
二. 恢復
我這裏是恢復所有庫 根據上方的定義的數據庫名數組 進行循環
/**
* mongo 數據庫恢復所有
*
* @return
* @param fileNameMongo
*/
public AjaxResult restoreMongo(String fileNameMongo) {
Runtime runtime = Runtime.getRuntime();
try {
for (String database : MONGO_DATA_BASE) {
String stmt =
"mongorestore "
+ " -d "
+ database
+ " --dir "
+ MONGO_FILE_PATH
+ fileNameMongo
+ "/"
+ database
+ " -h"
+ MONGO_HOST_PORT
+" -u"+GlobalUtil.MONGO_USER_NAME
+" -p"+GlobalUtil.MONGO_PASS_WORD
+" --authenticationDatabase admin";
//--------------------------------
// "mongorestore "
// + " -h "
// + MONGO_HOST_PORT
// + " -d "
// + database
// + " --dir "
// + MONGO_FILE_PATH
// + fileNameMongo
// + "/"
// + database;
log.info("恢復命令:{}", stmt);
String[] command = {"/bin/sh", "-c", stmt};
// String[] command = {"cmd", "/c", stmt};
Process process = runtime.exec(command);
OutputStream outputStream = process.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "utf-8");
writer.flush();
outputStream.close();
writer.close();
if (process.waitFor()==0) {
dumpService.insertDump(
new Dump(
SecurityUtils.getUsername(),
MONGO_HOST_PORT,
fileNameMongo,
"Mongo恢復",
MONGO_FILE_PATH + fileNameMongo,
new DateTime()));
log.info(fileNameMongo + "恢復成功");
}
}
return AjaxResult.success("Mongo數據還原成功");
} catch (Exception e) {
e.printStackTrace();
return AjaxResult.error("Mongo 數據還原失敗");
}
}
(三)小驚喜
貼上我項目中 查看 備份文件名 列表工具類
/**
* @author leilei
* @version 1.0
* @date 2020/4/10 16:35
* @desc: 獲取文件
*/
public class GetFileUtil {
/**
* 獲取Mysql 存儲記錄列表
* @return
*/
public static List<DumpFile> getMysqlFileList() {
File file = new File(DumpDatabaseUtil.FILE_PATH);
File[] fileList = file.listFiles();
if (fileList != null && fileList.length > 0) {
List<DumpFile> list = new ArrayList<>();
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isFile()) {
String fileName = fileList[i].getName();
if (".sql".equals(fileName.substring(fileName.lastIndexOf(".")))) {
DumpFile filelist = new DumpFile();
filelist.setFileName(fileName);
list.add(filelist);
}
}
}
return list;
}
return new ArrayList<DumpFile>();
}
/**
* 獲取Mongo 存儲 目錄列表
* @return
*/
public static List<DumpFile> getMongoFileList() {
File file = new File(DumpDatabaseUtil.MONGO_FILE_PATH);
File[] fileList = file.listFiles();
if (fileList != null && fileList.length > 0) {
List<DumpFile> list = new ArrayList<>();
for (int i = 0; i < fileList.length; i++) {
String fileName = fileList[i].getName();
DumpFile filelist = new DumpFile();
filelist.setFileName(fileName);
list.add(filelist);
}
return list;
}
return new ArrayList<DumpFile>();
}
}
/**
* @author leilei
* @version 1.0
* @date 2020/4/10 16:24
* @desc: 備份文件 或文件夾名
*/
@Data
public class DumpFile {
private String fileName;
}
(四) 成果展示
查看服務器上路徑 是否存在備份文件
可以看到 備份 恢復功能已經大功告成 。