文章目录

  • (一) 原生的数据库备份命令
  • (二)java 代码实现
  • Mysql
  • 一. 备份
  • 二. 恢复
  • Mongo
  • 一. 备份
  • 二. 恢复
  • (三)小工具
  • 贴上我项目中 查看 备份文件名 列表工具类
  • (四) 成果展示



SpringBoot 项目中 对Mysql ,MongoDB 数据库进行备份恢复操作

版本说明 本次项目 mysql版本为5.7.29 mongo版本为4.2.5

(一) 原生的数据库备份命令

mysql

# 备份命令
mysqldump -hIp地址 -u用户名 -p密码 需备份的数据库 > 备份地址
#恢复命令
mysql -hIp地址 -u用户名 -p密码 需还原的数据库 < 备份sql文件位置

mongodb

mongo 备份 与mysql 不同 mysql 会默认将一个库中的所有表 备份在一个sql文件中 ,而mongo备份则会根据你选择备份的数据库名生成一个文件夹

文件夹中存放 库中所有的文档表 后缀为.bson

# 备份命令  Mongo库无密码时
mongodump -h Ip:端口 备份数据库名 -o 备份文件夹位置

# 备份命令  Mongo库有密码时
mongodump -d 备份数据库名 -o 备份文件夹位置 -hIP-u用户名 -p密码 --authenticationDatabase admin

#恢复命令 	Mongo库无密码时
mongorestore -h Ip:端口 -d 恢复数据库名 --dir 要恢复的文件夹位置

#恢复命令	Mongo库有密码时
mongorestore -d 恢复数据库名 --dir 要恢复的文件夹位置 -hIp -u用户名 -p密码 --authenticationDatabase admin

java 项目中对Mongo mysql 等数据库备份其实主要使用了 java.lang.Runtime 这个类

Runtime 类的高级用法就自行百度吧 哈哈

下边开始我们的实践操作

(二)java 代码实现

首先贴上我的自定义的常量 包含了 要备份的mysql mongo的Ip 账户密码, 备份路径等信息

/** 需备份恢复MysqlIP */
  public static String MONGO_HOST_PORT = GlobalUtil.Ip+":27017";
  /** 需要备份的Mongo数据库名 */
  public static String[] MONGO_DATA_BASE = {"库1", "库2", "库3"};

  /** Mongo备份文件 路径  分win路径和linux 路径*/
//  public static String MONGO_FILE_PATH = "d:\\cattleDatabase\\mongo\\";
  public static String MONGO_FILE_PATH = "/webtest/dataBase/mongo/";

  // -------------------------------------------------------------
  /** 需备份恢复MysqlIP */
  public static String HOST_PORT = GlobalUtil.Ip;

  /** 需要备份的Mysql数据库名 */
  public static String DATA_BASE = "cattle-vue";

  /** MYsql备份文件 路径 分win路径和linux 路径 */
  public static String FILE_PATH = "/webtest/dataBase/mysql/";
//  public static String FILE_PATH = "d:\\cattleDatabase\\mysql\\";
/** 操控IP 备份 停服 指定随机等 */
  public static final String Ip = "xxxxxxx";

  /** 操作mongo账户 */
  public static final String MONGO_USER_NAME = "xxx";

  /** 操作mongo密码 */
  public static final String MONGO_PASS_WORD = "xxxx";

  /** 操作mysql账户 */
  public static final String USER_NAME = "xxx";

  /** 操作mysql密码 */
  public static final String PASS_WORD = "xxxxxx";

首先需要注意的点 备份文件路径 分linux 系统路径 和我用的Win路径 当然 在两种操作系统上 命令行打开以及使用的方式也是不同的

linux 上

String[] command = {"/bin/sh", "-c",  stmt};

win上

String[] command = {"cmd", "/c", stmt};

stmt 为我们在控制台执行的操作命令 exmaple: mysqldump -h 192.168.10.120 xxxxxxx

下方的 dumpService 是我为了将 备份恢复记录保存到数据库中的 保存服务类接口

Mysql
一. 备份
/**
   * Mysql 数据备份
   *
   * @return
   */
  public AjaxResult dumpMysql() {

    log.info("当前数据库备份时间:{}", DateUtil.now());
    // 获取Runtime实例
    Runtime runtime = Runtime.getRuntime();
    String mysqlFileName=DATA_BASE + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss") + ".sql";
    // 执行CMD命令
    String stmt =
        "mysqldump "
            + "-h "
            + HOST_PORT
            + " -u "
            + GlobalUtil.USER_NAME
            + " -p"
            + GlobalUtil.PASS_WORD
            + " "
            + DATA_BASE
            + " > "
            + FILE_PATH
            + mysqlFileName;
    log.info("数据库备份命令为:{}", stmt);
    if (!FileUtil.exist(FILE_PATH)) {
      FileUtil.mkdir(FILE_PATH);
    }
    try {
//      String[] command = {"cmd", "/c", stmt};
      String[] command = {"/bin/sh", "-c",  stmt};
      Process process = runtime.exec(command);
      InputStream input = process.getInputStream();
      System.out.println(IOUtils.toString(input, "UTF-8"));
      // 若有错误或者警告信息则输出
      InputStream errorStream = process.getErrorStream();
      System.out.println(IOUtils.toString(errorStream, "gbk"));
      if (input != null) {
        input.close();
        if (errorStream != null) {
          errorStream.close();
        }
      }
      if (process.waitFor() == 0) {
        log.info("Mysql 数据库备份成功,备份文件名:{}", mysqlFileName);
        dumpService.insertDump(new Dump(SecurityUtils.getUsername(),HOST_PORT+":3306",mysqlFileName,"Mysql备份",FILE_PATH, new DateTime()));
        return AjaxResult.success("数据库备份成功,备份文件所在地:" + FILE_PATH + mysqlFileName);
      } else {
        return AjaxResult.error("网络异常 数据库备份失败");
      }
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("网络异常");
    }
  }
二. 恢复
/**
   * mysql 数据恢复
   *
   * @param fileName
   * @return
   */
  public AjaxResult restoreMysql(String fileName) {
    try {
      Runtime runtime = Runtime.getRuntime();
      String realFilePath = FILE_PATH + fileName;
      String cmd =
          "mysql  -h "
              + HOST_PORT
              + " -u"
              + GlobalUtil.USER_NAME
              + " -p"
              + GlobalUtil.PASS_WORD
              + " "
              + DATA_BASE
              + " <  "
              + realFilePath;

//      String[] command = {"cmd", "/c", cmd};
      String[] command = {"/bin/sh", "-c", cmd};
      Process process = runtime.exec(command);
      OutputStream outputStream = process.getOutputStream();
      OutputStreamWriter writer = new OutputStreamWriter(outputStream, "utf-8");
      writer.flush();
      outputStream.close();
      writer.close();
      if (process.waitFor() == 0) {
        dumpService.insertDump(
            new Dump(
                SecurityUtils.getUsername(),
                HOST_PORT + ":3306",
                fileName,
                "Mysql恢复",
                realFilePath,
                new DateTime()));
        return AjaxResult.success("还原的备份文件" + DumpDatabaseUtil.FILE_PATH + fileName + "成功");
      } else {
        return AjaxResult.error("网络异常 数据库备份失败");
      }
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("网络异常 数据库备份失败");
    }
  }
Mongo
一. 备份
/**
   *
   * mongo 库备份
   *
   * @return
   */
  public AjaxResult dumpMongo() {
    Runtime runtime = Runtime.getRuntime();
    String MongoFileName="mongo" + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss");
    try {
      for (String database : MONGO_DATA_BASE) {
        String stmt =
            "mongodump  "
                + " -d "
                + database
                + " -o "
                + MONGO_FILE_PATH
                + MongoFileName
                +"/"
                + " -h "
                + MONGO_HOST_PORT
                +" -u"+GlobalUtil.MONGO_USER_NAME
                +" -p"+GlobalUtil.MONGO_PASS_WORD
                +" --authenticationDatabase admin";
            //-----------------------------------------


//                "mongodump  "
//                + " -h "
//                + MONGO_HOST_PORT
//                + " -d "
//                + database
//                + " -o "
//                + MONGO_FILE_PATH
//                + MongoFileName
//                +"/";

        log.info("Mongo数据库备份命令为:{}", stmt);
        if (!FileUtil.exist(MONGO_FILE_PATH)) {
          FileUtil.mkdir(MONGO_FILE_PATH);
        }
        String[] command = {"/bin/sh", "-c", stmt};
//        String[] command = {"cmd", "/c", stmt};
        Process process = runtime.exec(command);
        InputStream input = process.getInputStream();
        System.out.println(IOUtils.toString(input, "UTF-8"));
        // 若有错误或者警告信息则输出
        InputStream errorStream = process.getErrorStream();
        System.out.println(IOUtils.toString(errorStream, "gbk"));
        if (input != null) {
          input.close();
          if (errorStream != null) {
            errorStream.close();
          }
        }
      }
      dumpService.insertDump(
          new Dump(
              SecurityUtils.getUsername(),
              MONGO_HOST_PORT,
              MongoFileName,
              "Mongo备份",
              MONGO_FILE_PATH + MongoFileName,
              new DateTime()));
      return AjaxResult.success("Mongo数据备份成功");
    } catch (IOException e) {
      e.printStackTrace();
      return AjaxResult.error("Mongo 数据备份失败");
    }
  }
二. 恢复

我这里是恢复所有库 根据上方的定义的数据库名数组 进行循环

/**
   * mongo 数据库恢复所有
   *
   * @return
   * @param fileNameMongo
   */
  public AjaxResult restoreMongo(String fileNameMongo) {
    Runtime runtime = Runtime.getRuntime();
    try {
      for (String database : MONGO_DATA_BASE) {
        String stmt =
            "mongorestore "
                + " -d "
                + database
                + " --dir "
                + MONGO_FILE_PATH
                + fileNameMongo
                + "/"
                + database
                + " -h"
                + MONGO_HOST_PORT
                +" -u"+GlobalUtil.MONGO_USER_NAME
                +" -p"+GlobalUtil.MONGO_PASS_WORD
                +" --authenticationDatabase admin";
            //--------------------------------
//            "mongorestore "
//                + " -h "
//                + MONGO_HOST_PORT
//                + " -d "
//                + database
//                + " --dir "
//                + MONGO_FILE_PATH
//                + fileNameMongo
//                + "/"
//                + database;
        log.info("恢复命令:{}", stmt);
       String[] command = {"/bin/sh", "-c", stmt};
//        String[] command = {"cmd", "/c", stmt};
        Process process = runtime.exec(command);
        OutputStream outputStream = process.getOutputStream();
        OutputStreamWriter writer = new OutputStreamWriter(outputStream, "utf-8");
        writer.flush();
        outputStream.close();
        writer.close();
        if (process.waitFor()==0) {
          dumpService.insertDump(
              new Dump(
                  SecurityUtils.getUsername(),
                  MONGO_HOST_PORT,
                  fileNameMongo,
                  "Mongo恢复",
                  MONGO_FILE_PATH + fileNameMongo,
                  new DateTime()));
          log.info(fileNameMongo + "恢复成功");
        }
      }
      return AjaxResult.success("Mongo数据还原成功");
    } catch (Exception e) {
      e.printStackTrace();
      return AjaxResult.error("Mongo 数据还原失败");
    }
  }
(三)小工具
贴上我项目中 查看 备份文件名 列表工具类
/**
 * @author leilei
 * @version 1.0
 * @date 2020/4/10 16:35
 * @desc: 获取文件
 */
public class GetFileUtil {

  /**
   * 获取Mysql 存储记录列表
   * @return
   */
  public static List<DumpFile> getMysqlFileList() {
    File file = new File(DumpDatabaseUtil.FILE_PATH);
    File[] fileList = file.listFiles();
    if (fileList != null && fileList.length > 0) {
      List<DumpFile> list = new ArrayList<>();
      for (int i = 0; i < fileList.length; i++) {
        if (fileList[i].isFile()) {
          String fileName = fileList[i].getName();
          if (".sql".equals(fileName.substring(fileName.lastIndexOf(".")))) {
            DumpFile filelist = new DumpFile();
            filelist.setFileName(fileName);
            list.add(filelist);
          }
        }
      }
      return list;
    }
    return new ArrayList<DumpFile>();
  }

  /**
   * 获取Mongo 存储 目录列表
   * @return
   */
  public static List<DumpFile> getMongoFileList() {
    File file = new File(DumpDatabaseUtil.MONGO_FILE_PATH);
    File[] fileList = file.listFiles();
    if (fileList != null && fileList.length > 0) {
      List<DumpFile> list = new ArrayList<>();
      for (int i = 0; i < fileList.length; i++) {
        String fileName = fileList[i].getName();
        DumpFile filelist = new DumpFile();
        filelist.setFileName(fileName);
        list.add(filelist);
      }
      return list;
    }
    return new ArrayList<DumpFile>();
  }
}
/**
 * @author leilei
 * @version 1.0
 * @date 2020/4/10 16:24
 * @desc: 备份文件 或文件夹名
 */
@Data
public class DumpFile {
  private String fileName;
}
(四) 成果展示

mongodb 恢复bson mongodb恢复数据库_mysql


mongodb 恢复bson mongodb恢复数据库_mysql_02

mongodb 恢复bson mongodb恢复数据库_java_03


mongodb 恢复bson mongodb恢复数据库_数据库_04


mongodb 恢复bson mongodb恢复数据库_java_05


mongodb 恢复bson mongodb恢复数据库_mysql_06


查看服务器上路径 是否存在备份文件

mongodb 恢复bson mongodb恢复数据库_数据库_07


mongodb 恢复bson mongodb恢复数据库_java_08


mongodb 恢复bson mongodb恢复数据库_mysql_09


mongodb 恢复bson mongodb恢复数据库_数据库_10

可以看到 备份 恢复功能已经大功告成 。