springboot 人大金仓 kingbase-备份还原,命令中带密码

news2025/7/9 6:30:43

命令带密码参考

Java代码实现国产人大金仓数据库备份还原需求-CSDN博客文章浏览阅读818次,点赞16次,收藏12次。本人在一次项目中,遇到了需要在系统管理中提供给用户备份还原系统数据的功能,由于项目特殊性,项目底层数据库使用了国产人大金仓数据库(版本V8)。由于本人也是第一次使用金仓数据库,所以在功能实现过程中,踩到了一些坑,特此记录一下,共大家参考,避免踩到和我一样的坑。所以:sys_dump -d 数据库名 -h 127.0.0.1 -p 54321 -U root -W 123456 这个指令是有问题的,于是我又打开了命令窗口,调试了指令发现指令语法错误 -W 123456。于是我get到了,便优化了我的指令。https://blog.csdn.net/weixin_44329740/article/details/135764084

1、工具类

根据驱动类型,选择执行的命令

1)DatabaseUtil 工具类

import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.fisec.common.enums.DatabaseTypeEnum;

import java.util.HashMap;

public class DatabaseUtil {

    /**
     * 根据数据库驱动类型,获取数据库类型
     *
     * @param dbDriver
     * @return
     */
    public static DatabaseTypeEnum getDbType(String dbDriver) {
        if (dbDriver.startsWith("com.mysql")) {
            return DatabaseTypeEnum.Mysql;
        }

        if (dbDriver.startsWith("com.kingbase")) {
            return DatabaseTypeEnum.KingBase;
        }

        return DatabaseTypeEnum.Unknown;
    }

    /**
     * 获取mysql备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String mysqlBackLinuxCmd(String dbHost, String dbName, String username, String pwd) {
        return String.format("mysqldump -h%s -u%s -p%s -R %s", dbHost,
                username, pwd, dbName);
    }

    /**
     * 获取mysql备份命令
     * 切换磁盘需要添加,并奇幻盘符下命令执行
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String mysqlBackWindowsCmd(String dbHost, String dbName, String username, String pwd) {
        return String.format("d: && cd D:/Program Files/MySQL/MySQL Server 8.0/bin && .\\mysqldump.exe -h%s -u%s -p%s -R %s", dbHost,
                username, pwd, dbName);
    }

    /**
     * 获取 人大金仓数据备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String mysqlBackCmd(String dbHost, String dbName, String username, String pwd) {
        if (SystemUtil.getOsInfo().isWindows()) {
            return mysqlBackWindowsCmd(dbHost, dbName, username, pwd);
        }
        return mysqlBackLinuxCmd(dbHost, dbName, username, pwd);
    }

    /**
     * 获取mysql备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String mysqlRecoveryWindowsCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {
        return String.format("d: && cd D:/Program Files/MySQL/MySQL Server 8.0/bin && .\\mysql.exe -h%s -u%s -p%s %s < %s", dbHost,
                username, pwd, dbName, sqlPath);
    }


    /**
     * 获取mysql备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String mysqlRecoveryLinuxCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {
        return String.format("mysql -h%s -u%s -p%s %s < %s", dbHost,
                username, pwd, dbName, sqlPath);
    }

    /**
     * 获取 人大金仓数据备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String mysqlRecoveryCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {
        if (SystemUtil.getOsInfo().isWindows()) {
            return mysqlRecoveryWindowsCmd(dbHost, dbName, username, pwd, sqlPath);
        }
        return mysqlRecoveryLinuxCmd(dbHost, dbName, username, pwd, sqlPath);
    }

    /**
     * 获取人大金仓的备份命令
     * 注:这里路径为 windows 默认路径 ,注版本为 V008R006C008B0014 路径需根据实际情况替换
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String kingBaseBackWindowsCmd(String dbHost, String dbName, String username, String pwd) {
        return StrUtil.format("cd C:/Program Files/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && sys_dump.exe \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",
                new HashMap<>() {{
                    put("dbHost", dbHost);
                    put("dbName", dbName);
                    put("username", username);
                    put("pwd", pwd);
                }});
    }

    /**
     * 获取人大金仓的备份命令 - windows 默认路径 ,注版本为 V008R006C008B0014
     * 路径需根据实际情况替换
     * 所有 java 执行 linux命令需添加前缀 /bin/bash -c
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String kingBaseBackLinuxCmd(String dbHost, String dbName, String username, String pwd) {
        return StrUtil.format("cd /opt/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && sys_dump \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",
                new HashMap<>() {{
                    put("dbHost", dbHost);
                    put("dbName", dbName);
                    put("username", username);
                    put("pwd", pwd);
                }});
    }

    /**
     * 获取人大金仓的恢复数据库命令
     * 注:这里路径为 windows 默认路径 ,注版本为 V008R006C008B0014 路径需根据实际情况替换
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String kingBaseRecoveryWindowsCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {
        return StrUtil.format("cd C:/Program Files/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && ksql.exe -f {sqlPath} \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",
                new HashMap<>() {{
                    put("dbHost", dbHost);
                    put("dbName", dbName);
                    put("username", username);
                    put("pwd", pwd);
                    put("sqlPath", sqlPath);
                }});
    }

    /**
     * 获取人大金仓的备份命令 - windows 默认路径 ,注版本为 V008R006C008B0014
     * 路径需根据实际情况替换
     * 所有 java 执行 linux命令需添加前缀 /bin/bash -c
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String kingBaseRecoveryLinuxCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {
        return StrUtil.format("cd /opt/Kingbase/ES/V8/KESRealPro/V008R006C008B0014/ClientTools/bin && ksql -f {} \"host={dbHost} port=54321 user={username} password={pwd} dbname={dbName}\"",
                new HashMap<>() {{
                    put("dbHost", dbHost);
                    put("dbName", dbName);
                    put("username", username);
                    put("pwd", pwd);
                    put("sqlPath", sqlPath);
                }});
    }

    /**
     * 获取 人大金仓数据备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String kingBaseBackCmd(String dbHost, String dbName, String username, String pwd) {
        if (SystemUtil.getOsInfo().isWindows()) {
            return kingBaseBackWindowsCmd(dbHost, dbName, username, pwd);
        }
        return kingBaseBackLinuxCmd(dbHost, dbName, username, pwd);
    }

    /**
     * 获取 人大金仓数据备份命令
     *
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String kingBaseRecoveryCmd(String dbHost, String dbName, String username, String pwd, String sqlPath) {
        if (SystemUtil.getOsInfo().isWindows()) {
            return kingBaseRecoveryWindowsCmd(dbHost, dbName, username, pwd, sqlPath);
        }
        return kingBaseRecoveryLinuxCmd(dbHost, dbName, username, pwd, sqlPath);
    }

    /**
     * 根据数据类型 获取执行的命令
     *
     * @param databaseTypeEnum
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String getDbBackCmd(DatabaseTypeEnum databaseTypeEnum, String dbHost, String dbName, String username, String pwd) {
        return switch (databaseTypeEnum) {
            case Mysql -> mysqlBackCmd(dbHost, dbName, username, pwd);
            case KingBase -> kingBaseBackCmd(dbHost, dbName, username, pwd);
            case Unknown -> null;
        };
    }

    /**
     * 获取数据的的备份命令
     *
     * @param dbDriver
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String getDbBackCmd(String dbDriver, String dbHost, String dbName, String username, String pwd) {
        return getDbBackCmd(getDbType(dbDriver), dbHost, dbName, username, pwd);
    }

    /**
     * 根据数据类型 获取执行的命令
     *
     * @param databaseTypeEnum
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String getDbRecoveryCmd(DatabaseTypeEnum databaseTypeEnum, String dbHost, String dbName, String username, String pwd, String sqlPath) {
        return switch (databaseTypeEnum) {
            case Mysql -> mysqlRecoveryCmd(dbHost, dbName, username, pwd, sqlPath);
            case KingBase -> kingBaseRecoveryCmd(dbHost, dbName, username, pwd, sqlPath);
            case Unknown -> null;
        };
    }

    /**
     * 获取数据的的备份命令
     *
     * @param dbDriver
     * @param dbHost
     * @param dbName
     * @param username
     * @param pwd
     * @return
     */
    public static String getDbRecoveryCmd(String dbDriver, String dbHost, String dbName, String username, String pwd, String sqlPath) {
        return getDbRecoveryCmd(getDbType(dbDriver), dbHost, dbName, username, pwd, sqlPath);
    }

}

依赖枚举 DatabaseTypeEnum 

public enum DatabaseTypeEnum {
    /**
     * mysql 数据库
     */
    Mysql("mysql"),
    /**
     * 人大金仓数据
     */
    KingBase("kingBase"),
    /**
     * 未知的数据库类型
     */
    Unknown("unknown");

    private final String value;

    DatabaseTypeEnum(String value) {
        this.value = value;
    }
}

2、备份调用

参数获取

@Value("${spring.datasource.driver-class-name}")
private String dbDriver;
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String dbUsername;
@Value("${spring.datasource.password}")
 private String pwd;

执行内容
String dbHost = dbUrl.split("//")[1].split(":")[0];
        String dbName = dbUrl.split("/")[3];
        // 去除问号及其后面的参数
        if (dbName.contains("?")) {
            dbName = dbName.split("\\?")[0];
        }

        String command = DatabaseUtil.getDbBackCmd(dbDriver, dbHost, dbName, dbUsername, pwd);
        log.info("数据备份命令:{}", command);

        // 创建进程构建器
        ProcessBuilder processBuilder = new ProcessBuilder();
        // window 用 cmd、linux 用 bash
        if (SystemUtil.getOsInfo().isWindows()) {
            processBuilder.command("cmd.exe", "/C", command); // 设置工作目录
        } else {
            processBuilder.command("/bin/bash", "-c", command); // 设置工作目录
        }
        // 启动进程
        Process process = processBuilder.start();

        InputStream errorStream = process.getErrorStream();
        InputStreamReader isr = new InputStreamReader(errorStream, "GBK");

        BufferedReader br = new BufferedReader(isr);
        String line;
        while ((line = br.readLine()) != null) {
            log.info(line);
        }
        br.close();
        isr.close();
        errorStream.close();
        if (process.waitFor() != 0) {
            log.error("数据备份失败");
            throw new Exception("备份失败");
        }

3、数据库恢复调用

恢复失败了,数据sql 脚本被执行,但是恢复失败了

String dbHost = dbUrl.split("//")[1].split(":")[0];
            String dbName = dbUrl.split("/")[3];
            // 去除问号及其后面的参数
            if (dbName.contains("?")) {
                dbName = dbName.split("\\?")[0];
            }

            assert file != null;
            String command = DatabaseUtil.getDbRecoveryCmd(dbDriver, dbHost, dbName, dbUsername, pwd, file.getAbsolutePath());

            // 创建进程构建器
            ProcessBuilder processBuilder = new ProcessBuilder();
            // window 用 cmd、linux 用 bash
            if (SystemUtil.getOsInfo().isWindows()) {
                processBuilder.command("cmd.exe", "/C", command); // 设置工作目录
            } else {
                processBuilder.command("/bin/bash", "-c", command); // 设置工作目录
            }
            // 启动进程
            Process process = processBuilder.start();

            InputStream errorStream = process.getErrorStream();
            InputStreamReader isr = new InputStreamReader(errorStream, StandardCharsets.UTF_8);

            BufferedReader br = new BufferedReader(isr);
            String line;
            while ((line = br.readLine()) != null) {
                log.info(line);
            }
            br.close();
            isr.close();
            errorStream.close();

            if (process.waitFor() != 0) {
                return CommonResult.fail("数据恢复失败");
            }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1593644.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何使用电商接口获取商品信息,价格,主图?

1、什么是电商接口&#xff1f; 电商接口是指用于实现电商平台与其他系统之间进行数据交互和功能调的一组规范和方法。通过电商接口&#xff0c;可以实现商品信息的获取、订单管理、支付处理、物流跟踪等功能。 常见的电商接口包括&#xff1a; 商品接口&#xff1a;用于获取…

BLDC的机械角度、电角度与换相时间

6步换相梯形控制&#xff0c;6步一个周期定义为电角度360 总电角度 极对数 * 机械角度 机械角度是指360&#xff0c;一个圆周角&#xff1b; 电角度度指转子转动的角度&#xff0c;从一个N极到下一个N极是360。从N极只到 S极&#xff0c;则转子只运行了180。由于一个电机中通…

Python数据分析案例40——电商直播间成交金额预测

承接上一篇案例电商直播间提取的特征&#xff0c;进而做一篇机器学习的案例&#xff0c;来预测直播间的成交金额。 Python数据分析案例39——电商直播间评论可视化分析&#xff08;LDA&#xff09; 1. 引言 1.1 直播电商与传统电商的比较 直播电商作为一种新兴的电子商务模式…

本地web项目启起来后,无法在浏览器(chrome)看到源码,从而无法打断点;Framework Ignore list

问题描述 本地web项目启起来后&#xff0c;无法在浏览器(chrome)看到源码&#xff0c;从而无法打断点 其他浏览器没看&#xff0c;开发环境一致专注于chrome&#xff08;其余浏览器有测试同事提缺陷了&#xff0c;才会去看&#xff09;&#xff0c;其余浏览器有没有这个问题&…

B端:拖拽功能有哪些框架扩展,用起来爽歪歪。

B端系统拖拽交互功能是指在企业级系统中&#xff0c;用户可以通过拖拽元素来实现交互操作的功能。这种交互方式可以提高用户的操作效率和用户体验&#xff0c;常见的应用场景包括拖拽排序、拖拽调整大小、拖拽改变位置等。 在实现拖拽交互功能时&#xff0c;可以使用多种技术和…

必备工具!16.8k star 的项目!帮助你快速清理重复文件

大家的笔记本是不是都使用了好多年&#xff1f;是不是硬盘里的文件越来越多&#xff0c;尤其是经常有一些重复的文件散落在系统的各个角落&#xff0c;不好找&#xff0c;也很占据空间。今天就给大家介绍一款好用的开源工具&#xff0c;帮助你简单快速的清理电脑里的重复文件—…

Vue3+.NET6前后端分离式管理后台实战(十三)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战&#xff08;十三&#xff09;已经在公众号发布有兴趣的可以关注一下&#xff01; 有兴趣的可以扫码关注&#xff01;

探索网络爬虫:技术演进与学习之路

网络爬虫及IP代理池 前言爬虫技术的演进最新的爬虫技术爬虫技术学习路线 前言 在信息时代&#xff0c;网络爬虫技术作为获取和处理网络数据的重要手段&#xff0c;已经成为数据科学、机器学习和许多商业应用的基石。从简单的HTML页面抓取到复杂的动态内容采集&#xff0c;爬虫…

Flex弹性布局详解

详解Flex弹性布局 1. 什么是Flex布局2. Flex布局核心概念1&#xff09;容器和属性定义2&#xff09;主轴和交叉轴定义3&#xff09;容器属性4&#xff09;项目属性 3. 优缺点 1. 什么是Flex布局 Flex全称为 “Flexible Box Layout”&#xff0c;即 “弹性盒布局”&#xff0c;旨…

Java应用CPU飙升和死锁排查实战教程

引言 在日常开发中&#xff0c;我们可能会遇到Java应用CPU飙升和死锁的问题。本文将通过实际案例&#xff0c;为大家介绍如何排查这些问题 Java应用CPU飙升和死锁排查步骤 先执行top命令&#xff0c;找到CPU占用比较高的进程再执行jstack 进程id > dump.txt找到进程中CPU…

软考127-上午题-【软件工程】-McCabe度量法

一、McCabe度量法 1-1、定义 McCabe 度量法是通过定义环路复杂度&#xff0c;建立程序复杂性的度量。 它基于一个程序模块的程序图中环路的个数。计算有向图G的环路复杂性的公式为&#xff1a; V(G) m - n 2 闭合区域 1 其中V(G)是有向图 G 中的环路个数&#xff0c;m 是…

[全网最全]2024MathorCup妈妈杯ABCD题成品论文33页+配套完整代码数据汇总

所有题目的每一小问解答&#xff08;含配套代码和数据&#xff09;都已经更新完毕&#xff0c;其中C题成品论文33页更新&#xff0c;B题论文更新&#xff0c;A题半成品论文21页完整解答代码数据。 &#xff08;完整版的资料放在文末了&#xff09; A题 移动通信网络中PCI规划问…

蓝桥杯嵌入式(G431)备赛笔记——第十一届第二场真题

关键代码&#xff1a;、 user.c: u32 adc_tick 0; // 定义一个无符号32位整型变量 adc_tick&#xff0c;用于记录上次ADC处理的时间戳 u32 r37_value 0; // 定义一个无符号32位整型变量 r37_value&#xff0c;用于存储ADC通道2的采样值 u32 r38_value 0; // 定义一个无符号…

AI常见关键术语

哈喽&#xff0c;大家好&#xff0c;我是小码哥&#xff0c;人工智能技术的快速发展带来了许多专业术语&#xff0c;这些词汇对于理解AI的工作原理和应用至关重要。以下是一些关键的AI术语&#xff0c;以及它们的专业解释和通俗总结。 一、核心概念 人工智能 (AI) 专业解释&am…

轻量带屏解决方案之恒玄芯片移植案例

本文章基于恒玄科技BES2600W芯片的欧智通 Multi-modal V200Z-R开发板 &#xff0c;进行轻量带屏开发板的标准移植&#xff0c;开发了智能开关面板样例&#xff0c;同时实现了ace_engine_lite、arkui_ui_lite、aafwk_lite、appexecfwk_lite、HDF等部件基于OpenHarmony LiteOS-M内…

AI预测体彩排3第3弹【2024年4月14日预测--第1套算法开始计算第3次测试】

今天咱们继续测试第1套算法和模型&#xff0c;今天是第3次测试&#xff0c;目前的测试只是为了记录和验证&#xff0c;不建议大家盲目跟买。我的目标仍旧是10次命中3-4次!~废话不多说了&#xff0c;直接上结果&#xff01; 2024年4月14日排3的七码预测结果如下 第一套&…

mybatis的一对多

业务&#xff1a;通常主表从表 查询&#xff0c;一对多关系&#xff0c;通常是先查主表&#xff0c;然后拿主表的 关联字段与从表关联。在代码中 通常用for 循环等方法给 从表的数据赋值&#xff0c;很麻烦&#xff0c;&#xff0c;&#xff0c;很麻烦。。。。 用mybatis的…

软考中级--网络工程师-计算机基础与理论第二节无线基础知识

IEEE802.11 规定了多种 WLAN 通信标准&#xff0c;其中&#xff08; &#xff09;与其他标准采用的频段不同&#xff0c;因而不能兼容。 A IEEE802.11a B IEEE802.11b C IEEE802.11g D IEEE802.11n 试题答案 正确答案&#xff1a; A 答案解析 IEEE 802.11a规定采用5GHz的 ISM频…

Python | Leetcode Python题解之第25题K个一组翻转链表

题目&#xff1a; 题解&#xff1a; class Solution:# 翻转一个子链表&#xff0c;并且返回新的头与尾def reverse(self, head: ListNode, tail: ListNode):prev tail.nextp headwhile prev ! tail:nex p.nextp.next prevprev pp nexreturn tail, headdef reverseKGroup…

关于时频分析的一些事-答知乎问(一)

从信号的时频谱图中可以提取什么特征&#xff1f; 基于时频谱图的特征一般包括能量特征、时域和频域拓展特征以及时频内禀特征。 基于时频图的能量特征 基于时频图的特征中&#xff0c;能量特征是最简单的一种&#xff0c;通过分析时频谱图中的能量分布特性而获取信号的时频…