本来想mybatis有没有实现数据库备份,然后用定时任务调用,但是更简单的方法是,利用java执行cmd,再执行mysql自己的mysqldump
的命令进行备份即可。
/**
* 备份数据库
* @param username
* @param password
* @param databasename
* @param fileName
* @throws Exception
*/
//mysqldump -h端口号 -u用户 -p密码 数据库 > d:/test.sql --备份D盘
//备份
public static void dataBaseDump(String username,String password,String databasename) throws Exception {
File file = new File("D:\\_Document\\fanmini\\backup");
if (!file.exists()) {
file.mkdir();
}
String fileName = databasename + "_" + DateUtils.getDate() + "_backup";
File datafile = new File(file + File.separator + fileName + ".sql");
if (datafile.exists()) {
log.error(fileName + "文件名已存在,请更换");
return;
}
//拼接cmd命令
//此处mysqldump需要为绝对路径,环境变量这里没法识别
String s = "cmd /c D:\\mysql-5.7.31-winx64\\bin\\mysqldump -hlocalhost -u" + username + " -p" + password + " --opt " + databasename + " > " + datafile;
log.info("数据库备份命令:{}", s);
Process exec = Runtime.getRuntime().exec(s);
if (exec.waitFor() == 0) {
log.info("数据库备份成功,备份路径为:" + datafile);
} else {
log.error("数据库备份失败,备份路径为:" + datafile + "备份命令为:" + s);
}
}
问题
部署到windows服务器后执行,发现对应目录下产生空sql文件。
排查后,注意到:
- 即使已经设置好环境变量,并且手动备份成功,这里java执行仍无法识别mysqldump命令,导致空输入流被导向sql文件,sql文件为空
- 命令-u后紧跟username,-p后紧跟password,否则命令错误
因此最后执行命令为(-hlocalhost可不写):
rt.exec("cmd /c D:\\mysql-5.7.31-winx64\\bin\\mysqldump -hlocalhost -uroot -p123456 --opt databaseName > d:\\bk.sql");
其中/c
意思是执行完其后的命令后关闭cmd窗口,目测一般执行cmd命令都要这么写:
cmd /c dir 是执行完dir命令后关闭命令窗口。
cmd /k dir 是执行完dir命令后不关闭命令窗口。
cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。
cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。