BackupIncreaseTask.java 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package com.hb.proj.sysbackup.service;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.util.Calendar;
  5. import java.util.Date;
  6. import org.apache.commons.io.FileUtils;
  7. import org.apache.commons.lang3.StringUtils;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import com.hb.proj.model.BackupLogPO;
  11. import com.hb.proj.model.BackupSchedulePO;
  12. import com.hb.proj.sys.service.DBBackupService;
  13. import com.hb.xframework.util.ApplicationContextUtils;
  14. import com.hb.xframework.util.DateUtil;
  15. /**
  16. * 增量备份任务(Select ...into oufile 也是一种逻辑备份方式,恢复速度比较快,但是只能备份表中的数据,不能包含表结构)
  17. * 备份区段:上次备份时间(没有则是1月前)至 当前时间
  18. * 通过load data的方式,实现回复还原操作(LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;)
  19. * @author cwen
  20. *
  21. */
  22. public class BackupIncreaseTask implements Runnable {
  23. private static final Logger logger = LoggerFactory.getLogger(BackupIncreaseTask.class);
  24. private BackupSchedulePO sche; //待执行的任务计划
  25. private BackupProperties properties; //备份配置属性
  26. private DBBackupService service;
  27. private String caller;
  28. public BackupIncreaseTask(BackupSchedulePO sche,BackupProperties properties,String caller) {
  29. this.caller=caller;
  30. this.sche=sche;
  31. this.properties=properties;
  32. this.service=ApplicationContextUtils.getBean("DBBackupService", DBBackupService.class);
  33. }
  34. @Override
  35. public void run() {
  36. logger.info("开始进行增量备份...");
  37. if(StringUtils.isBlank(sche.getBackupObj())) {
  38. logger.info("未找到备份数据表,取消操作");
  39. return;
  40. }
  41. BackupLogPO log=null,prlog=null;
  42. try {
  43. String[] tabs=sche.getBackupObj().split(";");
  44. for(String tab : tabs) {
  45. if(!tab.contains(":")) {
  46. logger.info("数据表{}配置不符合增量备份要求【table:field】,取消操作",tab);
  47. continue;
  48. }
  49. log=buildLog(tab);
  50. log.setDataEndTime(new Date());
  51. service.saveBackupLog(log);
  52. prlog=service.getLastBackup(log.getTaskName());
  53. service.createBackup(buildSQL(tab,getDataTime(prlog),log.getDataEndTime(),log.getBackupFile()));
  54. log.setStatus(BackupLogPO.STAT_SUCCESS);
  55. log.setEndTime(new Date());
  56. service.saveBackupLog(log);
  57. }
  58. }
  59. catch(Exception e) {
  60. e.printStackTrace();
  61. logger.error("备份进程出现异常,任务取消:{}",e.getMessage());
  62. if(log!=null) {
  63. log.setStatus(BackupLogPO.STAT_FAILED);
  64. log.setEndTime(new Date());
  65. log.setNote("任务执行出错");
  66. service.saveBackupLog(log);
  67. }
  68. }
  69. }
  70. private String buildSQL(String tab,Date startTime,Date endTime,String saveFile) {
  71. String[] tabField=tab.split(":");
  72. StringBuilder sql=new StringBuilder();
  73. sql.append("select * from "+tabField[0]);
  74. sql.append(" where "+tabField[1]+" > '"+DateUtil.format(startTime, "yyyy-MM-dd HH:mm:ss")+"' and "+tabField[1]+" <= '"+DateUtil.format(endTime, "yyyy-MM-dd HH:mm:ss")+"' into outfile '"+saveFile+"'");
  75. return sql.toString();
  76. }
  77. private BackupLogPO buildLog(String tab) throws IOException {
  78. tab=tab.split(":")[0];
  79. String fileName="["+tab+"]"; //sche.getScheduleName()+"["+tab+"]";
  80. BackupLogPO backupLog=new BackupLogPO(fileName,sche.getScheduleId(),BackupLogPO.STAT_RUNNING);
  81. String path=properties.getSavePath();
  82. //sql语句中的分隔符特殊处理
  83. /*if(!path.endsWith(File.separator)) {
  84. path+=File.separator;
  85. }
  86. path+=DateUtil.format(new Date(), "yyyyMM")+File.separator;
  87. */
  88. path+="\\\\"+DateUtil.format(new Date(), "yyyyMM")+"\\\\";
  89. FileUtils.forceMkdir(new File(path));
  90. backupLog.setBackupFile(path+fileName+DateUtil.format(new Date(), "yyyyMMddHHmm")+".sql");
  91. backupLog.setOperator(caller);
  92. return backupLog;
  93. }
  94. /**
  95. * 默认从上次备份时间开始,无上次备份则从前一天开始
  96. * @param log
  97. * @return
  98. */
  99. private Date getDataTime(BackupLogPO log) {
  100. if(log==null || log.getDataEndTime()==null) {
  101. Calendar ca=Calendar.getInstance();
  102. ca.add(Calendar.DAY_OF_MONTH, -1);
  103. return ca.getTime();
  104. }
  105. else {
  106. return log.getDataEndTime();
  107. }
  108. }
  109. }