​ 达梦数据库远程操作进行备份与恢复在网络上的参考资料与博客比较少,这里记录下项目中用到的方法。

1、工具类

​ 首先是编写工具类,用于连接远程服务器、生成相应操作的命令、执行相关命令。

  1. package com.fongtech.cli.common.util;
  2. import ch.ethz.ssh2.Session;
  3. import com.jcraft.jsch.*;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.apache.commons.lang3.ArrayUtils;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.slf4j.Logger;
  8. import org.slf4j.LoggerFactory;
  9. import ch.ethz.ssh2.Connection;
  10. import ch.ethz.ssh2.StreamGobbler;
  11. import java.io.*;
  12. import java.text.SimpleDateFormat;
  13. import java.util.Date;
  14. /**
  15. *工具类
  16. */
  17. @Slf4j
  18. public class DMruntimeUtil {
  19. private static final String DEFAULT_CHARSET = "utf-8";
  20. private static final Logger LOGGER = LoggerFactory.getLogger(DMruntimeUtil.class);
  21. /**
  22. * 登录主机
  23. *
  24. * @return 登录成功返回true,否则返回false
  25. */
  26. public static Connection login(String ip, String userName, String userPwd) {
  27. boolean flg = false;
  28. Connection conn = null;
  29. try {
  30. conn = new Connection(ip);
  31. conn.connect();// 连接
  32. flg = conn.authenticateWithPassword(userName, userPwd);// 认证
  33. if (flg) {
  34. log.info("=========登录服务器成功=========" + conn);
  35. return conn;
  36. }
  37. } catch (IOException e) {
  38. log.error("=========登录服务器失败=========" + e.getMessage());
  39. e.printStackTrace();
  40. }
  41. return conn;
  42. }
  43. /**
  44. * 远程执行shll脚本或者命令
  45. *
  46. * @param cmd 即将执行的命令
  47. * @return 命令执行完后返回的结果值
  48. */
  49. public static String execute(Connection conn, String cmd) {
  50. String result = "";
  51. try {
  52. if (conn != null) {
  53. Session session = conn.openSession();// 打开一个会话
  54. session.execCommand(cmd);// 执行命令
  55. result = processStdout(session.getStdout(), DEFAULT_CHARSET);
  56. // System.out.println("-----------result:"+result);
  57. // 如果为得到标准输出为空,说明脚本执行出错了
  58. if (StringUtils.isBlank(result)) {
  59. LOGGER.info("得到标准输出为空,链接conn:" + conn + ",执行的命令:" + cmd);
  60. result = processStdout(session.getStderr(), DEFAULT_CHARSET);
  61. } else {
  62. LOGGER.info("执行命令成功,链接conn:" + conn + ",执行的命令:" + cmd);
  63. }
  64. // System.out.println(result);
  65. conn.close();
  66. session.close();
  67. }
  68. } catch (IOException e) {
  69. LOGGER.info("执行命令失败,链接conn:" + conn + ",执行的命令:" + cmd + " " + e.getMessage());
  70. e.printStackTrace();
  71. }
  72. return result;
  73. }
  74. /**
  75. * 解析脚本执行返回的结果集
  76. *
  77. * @param in 输入流对象
  78. * @param charset 编码
  79. * @return 以纯文本的格式返回
  80. */
  81. private static String processStdout(InputStream in, String charset) {
  82. InputStream stdout = new StreamGobbler(in);
  83. StringBuffer buffer = new StringBuffer();
  84. ;
  85. try {
  86. BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
  87. String line = null;
  88. while ((line = br.readLine()) != null) {
  89. buffer.append(line + "\n");
  90. }
  91. } catch (UnsupportedEncodingException e) {
  92. LOGGER.error("解析脚本出错:" + e.getMessage());
  93. e.printStackTrace();
  94. } catch (IOException e) {
  95. LOGGER.error("解析脚本出错:" + e.getMessage());
  96. e.printStackTrace();
  97. }
  98. return buffer.toString();
  99. }
  100. /**
  101. * 同城-部分备份
  102. * 数据库的指定表(包括表结构与数据)
  103. *
  104. * @param hostip 数据库IP地址
  105. * @param dbName 数据库名称
  106. * @param username 用户名
  107. * @param password 密码
  108. * @param tables 待备份的表数组 ./dexp USERID=SYSDBA/SYSDBA@ip:port
  109. * FILE=db_str2.dmp LOG=db_str2.log TABLES=DEV.SYS_USER
  110. * DIRECTORY=/opt/dameng/dmdbms/dm7data/EVAL/dexp"
  111. */
  112. public static String dumpByTables(String hostip, String dbName, String username, String password, String tables,
  113. String name,String dexpFileUrl) {
  114. StringBuffer command = new StringBuffer("./dexp ");
  115. command.append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
  116. .append(" FILE=").append(name).append(".dmp ").append(" LOG=").append(name).append(".log ")
  117. .append(" TABLES=").append(tables);
  118. // int length = command.length();
  119. String newCommand = command.toString() + " DIRECTORY="+dexpFileUrl;
  120. log.info("命令= " + newCommand);
  121. return newCommand;
  122. }
  123. /**
  124. * 同城-全部备份
  125. * 数据库(包括表结构与数据)
  126. *
  127. * @param hostip 数据库IP地址
  128. * @param dbName 数据库名称
  129. * @param username 用户名
  130. * @param password 密码
  131. * <p>
  132. * 整个数据库导出 ./dexp USERID=SYSDBA/SYSDBA@ip:port
  133. * FILE=db_str2.dmp
  134. * DIRECTORY=/opt/dameng/dmdbms/dm7data/EVAL/dexp
  135. * LOG=db_str2.log FULL=Y
  136. */
  137. public static String dumpDB(String hostip, String dbName, String username, String password, String name,String dexpFileUrl) {
  138. StringBuffer command = new StringBuffer("./dexp ");
  139. command.append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
  140. .append(" FILE=").append(name).append(".dmp")
  141. .append(" DIRECTORY=").append(dexpFileUrl)
  142. .append(" SCHEMAS=\"SYSDBA\" ")
  143. // .append(" LOG=").append(name).append(".log FULL=Y");
  144. .append(" LOG=").append(name).append(".log ");
  145. log.info("命令= " + command.toString());
  146. return command.toString();
  147. }
  148. /**
  149. * 同城 - 删除备份文件和备份日志
  150. *
  151. * @param fileName
  152. * @return
  153. * 删除命令: rm -rf 20200610182738198data.log 20200610182738198data.dmp 20200611153735300dataRecover.log
  154. */
  155. public static String delFile(String fileName) {
  156. StringBuffer command = new StringBuffer("rm -rf ");
  157. command.append(fileName+".log ").append(fileName+".dmp ")
  158. .append(fileName+"Recover.log ");
  159. log.info("命令= " + command.toString());
  160. return command.toString();
  161. }
  162. /**
  163. * 本地 ---数据库恢复
  164. * @param hostip
  165. * @param dbname
  166. * @param username
  167. * @param password
  168. * @param dir
  169. * @return
  170. * 恢复命令./dimp USERID=SYSDBA/SYSDBA FILE=/mnt/data/dexp/db_str.dmp LOG=db_str.log
  171. * DIRECTORY=/mnt/data/dimp
  172. */
  173. public static String dimpByTables(String hostip,String dbname, String username, String password, String dir,String fileName){
  174. StringBuffer command = new StringBuffer("./dimp ");
  175. command.append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
  176. // .append(" FILE=").append(dbname).append(".dmp")
  177. .append(" FILE=").append("/home/fongtech/statistic/backup/").append(fileName).append(".dmp")
  178. .append(" SCHEMAS=\"SYSDBA\" ")
  179. .append(" DIRECTORY=").append(dir)
  180. .append(" TABLE_EXISTS_ACTION=APPEND ")//恢复被删除的数据
  181. // .append(" LOG=").append(dbname).append(".log FULL=Y");
  182. .append(" LOG=").append(fileName).append("Recover.log "); //去掉 FULL=y
  183. log.info("命令= " + command.toString());
  184. return command.toString();
  185. }
  186. /**
  187. * 异域--部分备份
  188. * @param hostip
  189. * @param username
  190. * @param password
  191. * @param name
  192. * @param reurl
  193. * @param pwd
  194. * @param port
  195. * @param installPath
  196. * @param dexpFileUrl
  197. * @return
  198. */
  199. public static String foreignDumpDB(String hostip, String username, String password,
  200. String name, String reurl, String pwd,
  201. String port, String installPath,String dexpFileUrl,String tables) {
  202. StringBuffer command = new StringBuffer("cd ");
  203. command.append(installPath).append(";")
  204. .append("./dexp ").append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
  205. .append(" FILE=").append(name).append(".dmp")
  206. .append(" DIRECTORY=").append(dexpFileUrl)
  207. .append(" LOG=").append(name).append(".log ")
  208. .append(" TABLES=").append(tables);
  209. return command.toString();
  210. }
  211. /**
  212. * 异域-全部备份
  213. *
  214. */
  215. public static String foreignFullDumpDB(String hostip, String username, String password, String name,
  216. String reurl, String pwd, String port,
  217. String installPath,String dexpFileUrl) {
  218. StringBuffer command = new StringBuffer("cd ");
  219. command.append(installPath).append(";")
  220. .append("./dexp ").append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
  221. .append(" FILE=").append(name).append(".dmp")
  222. .append(" DIRECTORY=").append(dexpFileUrl)
  223. .append(" LOG=").append(name).append(".log FULL=Y;");
  224. return command.toString();
  225. }}
2、实现

​ 登录服务器和数据库的 ip 和账户密码等按照实际情况设置。

​ 文件存储位置和达梦数据库 /bin 等按照实际情况设置。

  1. //用于登录服务器
  2. private String userIp = "xx.xxx.xxx.xx";
  3. private String userName = "root";
  4. private String userPwd = "123456";
  5. //用于登录数据库
  6. private String hostip = "xx.xxx.xxx.xx";
  7. private String dbname = "SYSDBA";
  8. private String username = "SYSDBA";
  9. private String password = "SYSDBA";
  10. //存储目录
  11. private String dir = "/home/fongtech/statistic/backup";
  12. //达梦数据库的 bin 的位置
  13. private String installPath = "/opt/dmdbms/bin";
  14. /**
  15. * 异步对数据库进行备份,并且更新对应任务与生成系统消息
  16. * @param userIp
  17. * @param userName
  18. * @param userPwd
  19. * @param hostip
  20. * @param dbname
  21. * @param username
  22. * @param password
  23. * @param filename
  24. * @param dir
  25. * @param copyType
  26. * @param user
  27. * @param ip
  28. * @param pwd
  29. * @param port
  30. * @param installPath
  31. * @return
  32. */
  33. @Transactional(rollbackFor = Exception.class)
  34. @Async
  35. public Map<String, Object> backups(String userIp,String userName,String userPwd,String hostip,
  36. String dbname,String username,String password,String filename,
  37. String dir,String copyType,String user,String ip,String pwd,String port,String installPath,Integer task_id){
  38. String result = null;
  39. String fileSize = "";
  40. Connection conn = DMruntimeUtil.login(userIp, userName, userPwd);
  41. // 本地备份
  42. if (copyType.equals("local")) {
  43. String dexpStr = DMruntimeUtil.dumpDB(hostip, dbname, username, password, filename,dir);
  44. String cmd = "cd /opt/dmdbms/bin;" + dexpStr;
  45. result = DMruntimeUtil.execute(conn, cmd);
  46. } else if (copyType.equals("foreignLands")) { //异地备份
  47. String reurl = user + "@" + ip + ":" + dir;
  48. //方式1:运行命令
  49. String cmd = DMruntimeUtil.foreignFullDumpDB(hostip, username, password, filename, reurl, pwd, port,installPath,dir);
  50. //方式2:运行脚本
  51. // String cmd = "sh /opt/dameng/dmdbms/shelldata/fulldexphand.sh " + filename + " " + user + "@"
  52. // + ip + ":" + dir + " " + pwd + " " + port;
  53. result = DMruntimeUtil.execute(conn, cmd);
  54. }
  55. Map<String, Object> map = new HashMap<String, Object>();
  56. if (result != null) {
  57. map.put("flag", "success");
  58. //获取文件大小 todo 待测试!!!!!!!!!!!!!
  59. conn = DMruntimeUtil.login(userIp, userName, userPwd);
  60. String sizeCmd = "cd "+dir+";"+" du -sh "+filename+".dmp";
  61. String resultSize = DMruntimeUtil.execute(conn, sizeCmd);
  62. if(resultSize.contains("M")){
  63. String[] ms = resultSize.split("M");
  64. fileSize = ms[0]+"M";
  65. }else if (resultSize.contains("K")){
  66. String[] ms = resultSize.split("K");
  67. fileSize = ms[0]+"K";
  68. }else if (resultSize.contains("G")){
  69. String[] ms = resultSize.split("G");
  70. fileSize = ms[0]+"G";
  71. }
  72. log.info("--------获取备份文件的大小 fileSize:"+fileSize);
  73. // System.out.println("-------resultSize:"+resultSize);
  74. // System.out.println("-------fileSize:"+fileSize);
  75. } else {
  76. map.put("flag", "failed");
  77. map.put("msg", "备份失败!");
  78. }
  79. // 如果执行成功,对任务进行更新,, 并且需要有消息提示
  80. CommonTask one = commonTaskService.query().eq(CommonTask::getId, task_id).getOne();
  81. // one.setTask_start(new Date());
  82. // System.out.println(one);
  83. if(result!=null){
  84. one.setTask_status("task_12");
  85. one.setTask_end(new Date());
  86. }else {
  87. one.setTask_status("task_15");
  88. one.setTask_end(new Date());
  89. }
  90. commonTaskService.saveBackupsTask(one,filename,fileSize,dir);
  91. return map;
  92. }

​ 上面的实现是备份,恢复和删除同理。

​ 参考博客:https://www.cnblogs.com/yjwww/p/12125802.html

版权声明:本文为superlinb原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/superlinb/p/13175832.html