使用说明:
1、根据具体需要修改db_bk下配置文件(dbbk_cfg.properties);
2、将db_bk包编译成db_bk.jar包;
3、用记事本等编辑器修改启动脚本(windows下修改setup.bat中的"do AT 22:00“ 将时间修改成自己想要的时间;linux下修改setup.sh中的"echo "0 22 * * 0,1,2,3,4,5,6 java -jar $PWD/db_bak.jar" >a.cron" 将22改成你想要的时间,具体请参考cron的使用);
4、将db_bk.jar、setup.bat、setup.sh拷到同一文件夹下。
5、(执行命令时请到脚本文件当前目录下执行)windows下执行setup.bat,linux下执行setup.sh,执行完成后系统将添加执行任务并根据设置的时间间隔完成备份。
/*
*备份ORACLE 数据库
*/
package db_bk;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author driftice
*/
public class OracleBackup {
private static String expFilePath;//导出文件路径
private static String logPath;
private static String logDir;//程序日志文件夹名
private static String dbConn;//数据库连接,如 user/pwd@sid
private static String otherCommand;//其他exp命令行条
private static int bkOfDay;//备份保存天数
private static Logger logger;
/**
* @param args the command line arguments
*/
//内部类
class StreamThread extends Thread {
InputStream is;
String type;
StreamThread(InputStream is, String type) {
this.is = is;
this.type = type;
}
public void run() {
try {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(type + ">" + line);
}
} catch (IOException ioe) {
logger.log(Level.WARNING, ioe.getMessage());
}
}
}
public static void main(String[] args) {
try {
OracleBackup ob = new OracleBackup();
ob.readCFG(); // 从配置文件得到参数
setLogger();//配置Logger
File file = new File(expFilePath);
if (!file.exists()) file.mkdir();
ob.delPastdueFile();//删除过期备份
expFilePath = file.toString() + File.separator;
String fileName = getNowTime("yyyy-MM-dd") + ".dmp";
String command = "EXP " + dbConn + " " + "FILE=" + "\"" + expFilePath + fileName + "\" " +
otherCommand + " LOG=\"" + expFilePath + getNowTime("yyyy-MM-dd") + ".log\"";
ob.RunBackup(command);
} catch (Exception ex) {
logger.log(Level.WARNING, ex.getMessage());
}
}
//读取dbbk_cfg配置文件
public void readCFG() {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("dbbk_cfg.properties");
Properties dbbk_cfg = new Properties();
try {
dbbk_cfg.load(inputStream);
expFilePath = URLDecoder.decode(dbbk_cfg.getProperty("expFilePath"),"utf-8");
logPath = URLDecoder.decode(dbbk_cfg.getProperty("logPath"),"utf-8");
logDir = URLDecoder.decode(dbbk_cfg.getProperty("logDir"),"utf-8");
dbConn = URLDecoder.decode(dbbk_cfg.getProperty("dbConn"),"utf-8");
otherCommand = URLDecoder.decode(dbbk_cfg.getProperty("otherCommand"),"utf-8");
bkOfDay = Integer.parseInt(dbbk_cfg.getProperty("bkOfDay"));
} catch (Exception e) {
logger.log(Level.WARNING, "读取配置文件错误:" + e.getMessage());
}
}
public void RunBackup(String command) {
try {
Process process = Runtime.getRuntime().exec(command);
new StreamThread(process.getInputStream(), "INFO").start();
new StreamThread(process.getErrorStream(), "INFO").start();
int status = process.waitFor();
if (status == 0) {
logger.log(Level.INFO, "["+getNowTime("yyyy-MM-dd")+"]成功备份!");
} else {
logger.log(Level.WARNING, "出现警告,请查看导出备份日志");
}
} catch (Exception ex) {
logger.log(Level.WARNING, ex.getMessage());
}
}
//删除过期文件,默认保留七天
public void delPastdueFile() {
try {
File file = new File(expFilePath);
String nowDay = getNowTime("yyyy-MM-dd");
String fileDay = "";
if (file.exists()) {
if (file.isDirectory()) {
File[] fileList = file.listFiles();
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isFile()) {
fileDay = fileList[i].getName();
if (getDays(nowDay, fileDay) >= bkOfDay && fileDay.substring(0, fileDay.indexOf(".")).matches("^\\d{4}-\\d{2}-\\d{2}$")) {
fileList[i].delete();
logger.log(Level.INFO, "过期备份数据:["+fileList[i].getName()+"]删除成功!");
}
}
}
}
}
} catch (Exception e) {
logger.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
//设置日志
public static void setLogger() {
logger = Logger.getLogger("sgg");
String logPathStr = logPath;
db_bk.LoggerUtil.file_name = logDir;
try {
LoggerUtil.setLogingProperties(logger, logPathStr);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//获取当天时间
public static String getNowTime(String dateformat) {
Date now = new Date();
SimpleDateFormat dateFormat = new SimpleDateFormat(dateformat);//可以方便地修改日期格式
String dateStr = dateFormat.format(now);
return dateStr;
}
/**
* 两个时间之间的天数
*
* @param date1
* @param date2
* @return
*/
public static long getDays(String date1, String date2) {
if (date1 == null || date1.equals("")) {
return 0;
}
if (date2 == null || date2.equals("")) {
return 0;
}
// 转换为标准时间
SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
java.util.Date date = null;
java.util.Date mydate = null;
try {
date = myFormatter.parse(date1);
mydate = myFormatter.parse(date2);
} catch (Exception e) {
return 0;
}
long day = (date.getTime() - mydate.getTime()) / (24 * 60 * 60 * 1000);
return day;
}
}
package db_bk;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
/**
* 日志输出到日志的文件夹下,
* 并且根据系统日期命名日志文件
* @author driftice
*
*/
public class LoggerUtil {
/** 存放的文件夹 **/
public static String file_name = "APPLOG";
/**
* 得到要记录的日志的路径及文件名称
* @return
*/
private static String getLogName(String logPathStr) {
StringBuffer logPath = new StringBuffer();
logPath.append(logPathStr);
logPath.append(File.separator+file_name);
File file = new File(logPath.toString());
if (!file.exists())
file.mkdirs();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
logPath.append(File.separator+sdf.format(new Date())+".log");
return logPath.toString();
}
/**
* 配置Logger对象输出日志文件路径
* @param logger
* @throws SecurityException
* @throws IOException
*/
public static void setLogingProperties(Logger logger,String logPathStr) throws SecurityException, IOException {
setLogingProperties(logPathStr,logger,Level.ALL);
}
/**
* 配置Logger对象输出日志文件路径
* @param logger
* @param level 在日志文件中输出level级别以上的信息
* @throws SecurityException
* @throws IOException
*/
public static void setLogingProperties(String logPathStr,Logger logger,Level level) {
FileHandler fh;
try {
fh = new FileHandler(getLogName(logPathStr),true);
logger.addHandler(fh);//日志输出文件
//logger.setLevel(level);
fh.setFormatter(new SimpleFormatter());//输出格式
//logger.addHandler(new ConsoleHandler());//输出到控制台
} catch (SecurityException e) {
logger.log(Level.SEVERE, "安全性错误", e);
} catch (IOException e) {
logger.log(Level.SEVERE,"读取文件日志错误", e);
}
}
}
参数配置文件(dbbk_cfg.properties):
#OracleBackup配置文件
#导出文件目录
expFilePath=D:/db_bk
#日志目录
logPath=D:/db_bk
#程序日志文件夹名
logDir=applog
#数据库连接,如 user/pwd@sid
dbConn=user/pwd@sid
#其他exp命令行条件
otherCommand=owner=(user) buffer=65536
#备份保存天数
bkOfDay=7
程序启动脚本(windows下:setup.bat linux下:setup.sh):
rem setup.bat
@ECHO 启动windows任务计划,于每日22:00执行备份程序
echo %cd%\db_bak.jar >a.txt
for /f "delims=" %%a in (a.txt) do AT 22:00 /every:M,T,W,Th,F,S,Su java -jar %%a
del a.txt
#setup.sh
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=wzs
HOME=/home/wzs
PWD=`pwd`
echo "已添加任务,每天22:00执行备份"
echo "0 22 * * 0,1,2,3,4,5,6 java -jar $PWD/db_bak.jar" >a.cron
crontab a.cron
rm a.cron