一、目的
- 使用java代码实现定时执行Mysql备份与还原。
二、思路
- 先写好一个定时器,每隔多少时间执行一次备份
- 备份方法为,通过java向命令行写入命令执行
- 首先在cmd中模拟备份,测试成功后
- 使用java代码实现数据备份功能
三、具体操作
(1) 命令行实现备份
-
第一次搜索的备份命令是
mysqldump -h localhost -u root -proot --databases shop --tables sc_cart sys_admin > d:\time_2018-11-14_09-54-55.sql
-
输入cmd,在命令行中输入以上代码,提示:mysqldump 不是内部或外部命令
-
于是将路径切换至mysql的bin目录下
-
再次尝试,报错10061再次尝试,报错10061
-
检查账号密码没有问题,多次尝试,找到原因为,默认端口号为3306,我的Mysql端口号为3307,在my.ini文件中将端口号改为3306后再次尝试
具体步骤 打开D:\Program Files\mysql5.7\mysql5.7\my.ini 将内容改为如下 [mysqld] port = 3306 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES skip-grant-tables
-
测试可正常进入数据库
-
测试备份命令,提示一个警告:Using a password on the command line interface
消除警告办法见文章:Mysql:备份提示Using a password on the command line interface -
修改my.ini文件后,输入新命令
mysqldump --defaults-extra-file=..\my.ini shop > d:\time_2018-11-14_10-08-38.sql
-
d盘下成功生成一个备份文件
-
命令行测试成功,下一步使用Java代码实现以上功能
(2)Java代码实现备份
-
java代码实现定时器
/** * 生成备份文件 * @throws Exception */ @Scheduled(cron="0 0 1 * * ?") //每天凌晨1点执行一次 public void backup() throws Exception{ System.out.println("############生成备份文件"); doBackup(); }
-
java代码实现写入命令行
/** * 执行生成备份 */ public static void doBackup(){ System.out.println("现在时间是"+new Date()); Runtime runtime = Runtime.getRuntime(); //获取Runtime实例 String user = "root"; String password = "root"; String database1 = "shop"; // 需要备份的数据库名 String table1 = "sc_cart"; String table2 = "sys_admin"; Date currentDate = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); String sdfDate = sdf.format(currentDate); String filepath = "d:\\time_" + sdfDate + ".sql"; // 备份的路径地址 //执行命令 String stmt = "mysqldump --defaults-extra-file=..\my.ini --databases "+database1+" --tables "+table1+" "+table2 +" > "+filepath; System.out.println(stmt); try { 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, "UTF-8")); } catch (IOException e) { e.printStackTrace(); } }
-
执行之后,备份文件生成,但大小为0,没有写入数据
控制台提示如下:
-
错误命令乱码,将utf-8改为gbk,报错提示:mysqldump 不是内部或外部命令
-
有了命令行测试的经验,原因为mysqldump路径不对,于是将mysqldump.exe考到命令行默认的位置
-
测试依旧提示:mysqldump 不是内部或外部命令
-
继续测试将代码改为
String stmt = "d:\\Program Files\\mysql5.7\\mysql5.7\\bin mysqldump --defaults-extra-file=..\\my.ini "+database1+" > "+filepath;
//将代码顺便简化,账号密码后直接跟数据库,不跟表名,直接备份整个数据库
//若不是备份整个数据库,可使用以下代码
//String stmt = "d:\mysqldump --defaults-extra-file=d:\my.ini " --databases “+database1+” --tables “+table1+” “+table2 +” > "+filepath; -
不是内部或外部命令也可通过修改环境变量实现,具体步骤见:Mysql:设置环境变量
-
测试提示:
-
这里的原因是命令行不识别空格,可将
program file
改为progra~1
;
也可将mysqldump.exe考到d盘根目录下,我这里使用第二种方法;
代码改为
String stmt = "d:\\mysqldump --defaults-extra-file=d:\\my.ini "+database1+" > "+filepath;
测试无报错,备份文件生成,数据写入成功。 -
最后将成功的代码贴在下面
/** * 执行生成备份 */ public static void doBackup(){ System.out.println("现在时间是"+new Date()); Runtime runtime = Runtime.getRuntime(); //获取Runtime实例 String database1 = "shop"; // 需要备份的数据库名 Date currentDate = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss"); String sdfDate = sdf.format(currentDate); String filepath = "d:\\time_" + sdfDate + ".sql"; // 备份的路径地址 //执行命令 String stmt = "d:\\mysqldump --defaults-extra-file=d:\\my.ini "+database1+" > "+filepath; System.out.println(stmt); try { 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")); } catch (IOException e) { e.printStackTrace(); } }
-
还原代码
注意:命令行中执行的是mysql
不是mysqldump
。/** * 还原数据库 */ public static void restore() { String database = "shop"; // 需要备份的数据库名 System.out.println("现在时间是" + new Date()); Runtime runtime = Runtime.getRuntime(); try { String filePath = "D:\\time_31.sql"; // sql文件路径 String stmt = "d:\\mysql --defaults-extra-file=d:\\my.ini "+database+"< " + filePath; System.out.println(stmt); String[] command = {"cmd", "/c", stmt}; Process process = runtime.exec(command); //若有错误信息则输出 InputStream errorStream = process.getErrorStream(); System.out.println(IOUtils.toString(errorStream, "gbk")); //等待操作 int processComplete = process.waitFor(); if (processComplete == 0) { System.out.println("还原成功."); } else { throw new RuntimeException("还原数据库失败."); } } catch (Exception e) { e.printStackTrace(); } } ```
-
若不将mysqldump移至D盘根目录,也可以将mysql的bin目录配置在环境变量中
前面步骤完成后安装好MySQL,为MySQL配置环境变量。MySQL默认安装在C:\Program Files下。
1)新建MYSQL_HOME变量,并配置:C:\Program Files\MySQL\MySQL Server 5.6
MYSQL_HOME:C:\Program Files\MySQL\MySQL Server 5.6
2)编辑path系统变量,将%MYSQL_HOME%\bin添加到path变量后。配置path环境变量,也可不新建MYSQL_HOME变量,而是直接将MySQL安装目录下的bin配置到path变量下,即:C:\Program
Files\MySQL\MySQL Server 5.6\binPath:%MYSQL_HOME%\bin
或Path:C:\Program Files\MySQL\MySQL Server 5.6\bin
参考文章:
https://www.aliyun.com/jiaocheng/1121105.html
https://blog.csdn.net/babylove_BaLe/article/details/78953584