一、目的
- 使用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