達夢數據庫備份-手動備份


本系列文章用Java實現達夢數據庫的備份還原功能,分為本地備份(本服務器),異地備份(備份到其他服務器),手動備份和定時任務備份,及數據還原功能。

1. 達夢數據庫備份還原分類:

  

  代碼主要通過dexp和dimp命令實現全庫和表級別的邏輯備份還原

邏輯導出和邏輯導入數據庫對象分為四種級別:數據庫級、用戶級、模式級和表級。四種級
別獨立互斥,不能同時存在。四種級別所提供的功能:
1) 數據庫級(FULL):導出或導入整個數據庫中的所有對象。
  例:./dimp USERID=SYSDBA/SYSDBA FILE=/mnt/data/dexp/db_str.dmp LOG=db_str.log FULL=Y DIRECTORY=/mnt/data/dimp
2)用戶級(OWNER):導出或導入一個或多個用戶所擁有的所有對象。
  例:./dimp USERID=SYSDBA/SYSDBA FILE=/mnt/data/dexp/db_str.dmp LOG=db_str.log OWNER=USER01 DIRECTORY=/mnt/data/dimp
3)模式級(SCHEMAS):導出或導入一個或多個模式下的所有對象。
  例:./dimp USERID=SYSDBA/SYSDBA FILE=/mnt/data/dexp/db_str.dmp LOG=db_str.log SCHEMAS=USER01 DIRECTORY=/mnt/data/dimp
4)表級(TABLE):導出或導入一個或多個指定的表或表分區。
  例:./dimp USERID=SYSDBA/SYSDBA FILE=/mnt/data/dexp/db_str.dmp LOG=db_str.log TABLES=table1,table2 DIRECTORY=/mnt/data/dimp
 
2. 手動備份 
 //yum文件
 dameng:
  dev:
   #數據庫服務器ip地址 ip:
ip
#服務器用戶名
userName: dmdba
#登錄密碼 userPwd:
123456  /**    *本地服務器的ip,username,pwd寫到配置文件yum中 */   @Value("${dameng.dev.ip}")   private String userIp;   @Value("${dameng.dev.userName}")   private String userName;   @Value("${dameng.dev.userPwd}")   private String userPwd;   /** * 手動備份 -- 部分備份    *@tnames 要備份的表名    *@copytype 備份類型 local本地 foreignLands異地    *@ip,port,user,pwd,dir 異地備份服務器的ip,port,用戶名,密碼,備份文件存放目錄 */ public Map<String, Object> dumpSQL(String tnames, String copyType, String ip, String port, String user, String pwd, String dir) { System.out.println("備份類型:" + copyType); String result = null; // 保存備份列表,備份文件名稱=數據庫id+T+時間,還原使用 SjglSjbflbParam param = new SjglSjbflbParam(); param.setCjlx(copyType); // 獲取服務器連接 if (ip != null && port != null && user != null && pwd != null && dir != null) { param.setIp(ip); param.setPort(port); param.setUsername(user); param.setRepassword(pwd); param.setDir(dir); } StringBuffer tids = new StringBuffer(); for (String s1 : ids) { tids.append(s1).append(","); } param.setTids(tids.toString().substring(0, tids.toString().length() - 1)); param.setBflx("1"); String filename = sjglSjbflbService.add(param);//將備份記錄保持到數據庫,還原使用 Connection conn = DMruntimeUtil.login(userIp, userName, userPwd); // 本地備份 if (copyType.equals("local")) { String dexpStr = DMruntimeUtil.dumpByTables(hostip, dbname, username, password, tnames, filename); String cmd = "cd /opt/dameng/dmdbms/bin;" + dexpStr; result = DMruntimeUtil.execute(conn, cmd); } else if (copyType.equals("foreignLands")) { // sh dexplocal.sh test2 DEV.SYS_USER root@ip:/opt/data pwd 22 String cmd = "sh /opt/dameng/dmdbms/shelldata/dexphand.sh " + filename + " " + tnames + " " + user + "@" + ip + ":" + dir + " " + pwd + " " + port; result = DMruntimeUtil.execute(conn, cmd); } /* * HttpHeaders headers = new HttpHeaders(); * headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); * headers.setContentDispositionFormData("attachment", "eval.sql"); */ Map<String, Object> map = new HashMap<String, Object>(); if (result != null) { map.put("flag", true); } else { map.put("flag", false); map.put("msg", "備份失敗!"); } return map; } /** * 手動備份 -- 全部備份 */ @RequestMapping("/dumpDB") @ResponseBody public Map<String, Object> dumpDataBase(String[] ids, String copyType, String ip, String port, String user, String pwd, String dir) { System.out.println("備份地點:" + copyType); String result = null; SjglSjbflbParam param = new SjglSjbflbParam(); param.setCjlx(copyType); // 獲取服務器連接 if (ip != null && port != null && user != null && pwd != null && dir != null) { param.setIp(ip); param.setPort(port); param.setUsername(user); param.setRepassword(pwd); param.setDir(dir); } param.setBflx("1"); String filename = sjglSjbflbService.add(param);//保持備份記錄,還原使用 Connection conn = DMruntimeUtil.login(userIp, userName, userPwd); // 本地備份 if (copyType.equals("local")) { String dexpStr = DMruntimeUtil.dumpDB(hostip, dbname, username, password, filename); String cmd = "cd /opt/dameng/dmdbms/bin;" + dexpStr; result = DMruntimeUtil.execute(conn, cmd); } else if (copyType.equals("foreignLands")) { String reurl = user + "@" + ip + ":" + dir; //方式1:運行命令 String cmd = DMruntimeUtil.foreignFullDumpDB(hostip, username, password, filename, reurl, pwd, port); //方式2:運行腳本 // String cmd = "sh /opt/dameng/dmdbms/shelldata/fulldexphand.sh " + filename + " " + user + "@" // + ip + ":" + dir + " " + pwd + " " + port; result = DMruntimeUtil.execute(conn, cmd); } Map<String, Object> map = new HashMap<String, Object>(); if (result != null) { map.put("flag", true); } else { map.put("flag", false); map.put("msg", "備份失敗!"); } return map; } }

 工具類DMruntimeUtil

import ch.ethz.ssh2.Session;
import com.jcraft.jsch.*;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.StreamGobbler;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *工具類
 */
public class DMruntimeUtil {

    private static final String DEFAULT_CHARSET = "utf-8";

    private static final  Logger LOGGER = LoggerFactory.getLogger(DMruntimeUtil.class);

    /**
     * 登錄主機
     *
     * @return 登錄成功返回true,否則返回false
     */
    public static Connection login(String ip, String userName, String userPwd) {

        boolean flg = false;
        Connection conn = null;
        try {
            conn = new Connection(ip);
            conn.connect();// 連接
            flg = conn.authenticateWithPassword(userName, userPwd);// 認證
            if (flg) {
                LOGGER.info("=========登錄成功=========" + conn);
                return conn;
            }
        } catch (IOException e) {
            LOGGER.error("=========登錄失敗=========" + e.getMessage());
            e.printStackTrace();
        }
        return conn;
    }

    /**
     * 遠程執行shll腳本或者命令
     *
     * @param cmd 即將執行的命令
     * @return 命令執行完后返回的結果值
     */
    public static String execute(Connection conn, String cmd) {
        String result = "";
        try {
            if (conn != null) {
                Session session = conn.openSession();// 打開一個會話
                session.execCommand(cmd);// 執行命令
                result = processStdout(session.getStdout(), DEFAULT_CHARSET);
                // 如果為得到標准輸出為空,說明腳本執行出錯了
                if (StringUtils.isBlank(result)) {
                    LOGGER.info("得到標准輸出為空,鏈接conn:" + conn + ",執行的命令:" + cmd);
                    result = processStdout(session.getStderr(), DEFAULT_CHARSET);
                } else {
                    LOGGER.info("執行命令成功,鏈接conn:" + conn + ",執行的命令:" + cmd);
                }
                System.out.println(result);
                conn.close();
                session.close();
            }
        } catch (IOException e) {
            LOGGER.info("執行命令失敗,鏈接conn:" + conn + ",執行的命令:" + cmd + "  " + e.getMessage());
            e.printStackTrace();
        }
        return result;
    }
  
 /**
     * 解析腳本執行返回的結果集
     *
     * @param in      輸入流對象
     * @param charset 編碼
     * @return 以純文本的格式返回
     */
    private static String processStdout(InputStream in, String charset) {
        InputStream stdout = new StreamGobbler(in);
        StringBuffer buffer = new StringBuffer();
        ;
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout, charset));
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line + "\n");
            }
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("解析腳本出錯:" + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            LOGGER.error("解析腳本出錯:" + e.getMessage());
            e.printStackTrace();
        }
        return buffer.toString();
    }

 /**
     * 同城-部分備份
     * 數據庫的指定表(包括表結構與數據)
     *
     * @param hostip   數據庫IP地址
     * @param dbName   數據庫名稱
     * @param username 用戶名
     * @param password 密碼
     * @param tables   待備份的表數組 ./dexp USERID=SYSDBA/SYSDBA@ip:port
     *                 FILE=db_str2.dmp LOG=db_str2.log TABLES=DEV.SYS_USER
     *                 DIRECTORY=/opt/dameng/dmdbms/dm7data/EVAL/dexp"
     */
    public static String dumpByTables(String hostip, String dbName, String username, String password, String tables,
                                      String name,String dexpFileUrl) {
        StringBuffer command = new StringBuffer("./dexp ");
        command.append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
                .append(" FILE=").append(name).append(".dmp ").append(" LOG=").append(name).append(".log ")
                .append(" TABLES=").append(tables);

//        int length = command.length();
        String newCommand = command.toString() + " DIRECTORY="+dexpFileUrl;
        System.out.println("命令=    " + newCommand);
        return newCommand;
    }

    /**
     * 同城-全部備份
     * 數據庫(包括表結構與數據)
     *
     * @param hostip   數據庫IP地址
     * @param dbName   數據庫名稱
     * @param username 用戶名
     * @param password 密碼
     *                 <p>
     *                 整個數據庫導出 ./dexp USERID=SYSDBA/SYSDBA@ip:port
     *                 FILE=db_str2.dmp
     *                 DIRECTORY=/opt/dameng/dmdbms/dm7data/EVAL/dexp
     *                 LOG=db_str2.log FULL=Y
     */
    public static String dumpDB(String hostip, String dbName, String username, String password, String name,String dexpFileUrl) {
        StringBuffer command = new StringBuffer("./dexp ");
        command.append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
                .append(" FILE=").append(name).append(".dmp")
                .append(" DIRECTORY=").append(dexpFileUrl)
                .append(" LOG=").append(name).append(".log FULL=Y");

        System.out.println("命令=    " + command.toString());
        return command.toString();
    }

    /**
     * 異域--部分備份
     * @param hostip
     * @param username
     * @param password
     * @param name
     * @param reurl
     * @param pwd
     * @param port
     * @param installPath
     * @param dexpFileUrl
     * @return
     */
    public static String foreignDumpDB(String hostip, String username, String password,
                                       String name, String reurl, String pwd,
                                       String port, String installPath,String dexpFileUrl,String tables) {
        StringBuffer command = new StringBuffer("cd ");
        command.append(installPath).append(";")
                .append("./dexp ").append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
                .append(" FILE=").append(name).append(".dmp")
                .append(" DIRECTORY=").append(dexpFileUrl)
                .append(" LOG=").append(name).append(".log ")
                .append(" TABLES=").append(tables);
        return command.toString();
    }


    /**
     * 異域-全部備份
     *
     */
    public static String foreignFullDumpDB(String hostip, String username, String password, String name,
                                           String reurl, String pwd, String port,
                                           String installPath,String dexpFileUrl) {
        StringBuffer command = new StringBuffer("cd ");
        command.append(installPath).append(";")
                .append("./dexp ").append("USERID=").append(username).append("/").append(password).append("@").append(hostip)
                .append(" FILE=").append(name).append(".dmp")
                .append(" DIRECTORY=").append(dexpFileUrl)
                .append(" LOG=").append(name).append(".log FULL=Y;");
        return command.toString();
    }
}

 

 
           
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM