本来想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指令,原窗口不会关闭。
