Title

mysql数据备份

简介

MyBatis Plus 并没有涉及备份操作,它只是一个强化版的 MyBatis,提供了更为便捷和优雅的操作方式。因此,如果需要对数据进行备份操作,需要借助其他技术和工具来实现。
一般来说,备份关系型数据库最常用的方式是使用数据库系统提供的备份和还原工具。例如,使用 MySQL 数据库系统可以通过 mysqldump 命令行工具或者其它 GUI 工具实现备份和还原。另外,也可以借助第三方的备份工具来实现自动备份,以保证数据的安全性和可靠性。

数据库备份代码

使用 mysqldump 实现备份的示例:

import java.io.File;
import java.io.IOException;
 
public class BackupMySQL {
    public static void main(String[] args) throws IOException, InterruptedException {
        String dbName = "test";
        String outputDir = "/backup";
        String outputFile = outputDir + "/" + dbName + ".sql";
        String mysqlUser = "root";
        String mysqlPassword = "";
 
        String[] cmdArray = new String[] { "mysqldump", "-u" + mysqlUser, "-p" + mysqlPassword, dbName, "-r", outputFile };
        Process p = Runtime.getRuntime().exec(cmdArray);
        p.waitFor();
        int exitValue = p.exitValue();
        if (exitValue != 0) {
            System.err.printf("Failed to backup database '%s', error code: %d.\n", dbName, exitValue);
        } else {
            System.out.printf("Database '%s' has been backed up to file '%s'.\n", dbName, outputFile);
        }
    }
}

上述代码使用了 Java 的 Runtime 类的 exec 方法执行了 mysqldump 命令,并将备份文件保存到指定目录下。

注意:
MySQL 的备份命令是命令行命令,因此需要通过 Runtime 类的 exec 方法启动一个新的进程来执行该命令。在执行完备份命令后,需要调用 Process 类的 waitFor 方法等待进程执行完毕,然后通过 Process 的 exitValue 方法获取进程的退出状态码来判断备份是否成功。备份文件的路径可以根据具体情况进行修改。如果需要实现备份文件的自动周期性备份,可以使用定时任务或者其他方式来实现。
备份操作可能会对数据库的性能和稳定性造成一定的影响,因此需要在适当的时间安排备份操作,以保证数据库的正常运行。同时,备份文件需要进行备份存储和恢复操作时需要注意文件的格式和完整性,以保证备份的有效性和恢复的可靠性。

MySQL备份表设计


CREATE TABLE IF NOT EXISTS `t_mysql_backups` (
    `id` INT ( 11 ) NOT NULL AUTO_INCREMENT COMMENT '主键id',
    `mysql_ip` VARCHAR ( 15 ) DEFAULT NULL COMMENT '数据库IP',
    `mysql_port` VARCHAR ( 5 ) DEFAULT NULL COMMENT '数据库端口',
    `mysql_cmd` VARCHAR ( 230 ) DEFAULT NULL COMMENT '备份命令',
    `mysql_back_cmd` VARCHAR ( 230 ) DEFAULT NULL COMMENT '恢复命令',
    `database_name` VARCHAR ( 20 ) DEFAULT NULL COMMENT '数据库名称',
    `backups_path` VARCHAR ( 50 ) DEFAULT NULL COMMENT '备份数据地址',
    `backups_name` VARCHAR ( 50 ) DEFAULT NULL COMMENT '备份文件名称',
    `operation` INT ( 11 ) DEFAULT NULL COMMENT '操作次数',
    `status` INT ( 1 ) DEFAULT NULL COMMENT '数据状态(1正常,-1删除)',
    `recovery_time` DATETIME DEFAULT NULL COMMENT '恢复时间',
    `create_time` DATETIME DEFAULT NULL COMMENT '备份时间',
    `table_name` varchar(255) DEFAULT NULL COMMENT '备份表名称',
    PRIMARY KEY ( `id` ),
INDEX baskups_index ( mysql_ip, mysql_port, backups_path, database_name,backups_name) USING BTREE COMMENT '索引'
) ENGINE = INNODB AUTO_INCREMENT = 1 CHARSET = UTF8 ROW_FORMAT = COMPACT COMMENT = 'MySQL数据备份表';

实体类设计

package com.zl.model.entity;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.Date;

@Data
@TableName("t_mysql_backups")
public class TSystemMysqlBackups {
    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * MySQL服务器IP地址
     */
    @TableField("mysql_ip")
    private String mysqlIp;

    /**
     * MySQL服务器端口号
     */
    @TableField("mysql_port")
    private String mysqlPort;

    /**
     * MySQL服务器端口号
     */
    @TableField("database_name")
    private String databaseName;

    /**
     * MySQL备份指令
     */
    @TableField("mysql_cmd")
    private String mysqlCmd;

    /**
     * MySQL恢复指令
     */
    @TableField("mysql_back_cmd")
    private String mysqlBackCmd;

    /**
     * MySQL备份存储地址
     */
    @TableField("backups_path")
    private String backupsPath;

    /**
     * MySQL备份文件名称
     */
    @TableField("backups_name")
    private String backupsName;

    /**
     * 操作次数
     */
    @TableField("operation")
    private Integer operation;

    /**
     * 数据状态
     */
    @TableField("status")
    private Integer status;

    /**
     * 恢复时间
     */
    @TableField("recovery_time")
    private Date recoveryTime;

    /**
     * 备份时间
     */
    @TableField("create_time")
    private Date createTime;

    /**
     * 备份表名
     */
    @TableField("table_name")
    private String tableName;
}

注解说明:

  • @Data:Lombok简化实体类注解,不了解的小伙伴可以查看我之前写过的Lombok | 框架师一文
  • @TableName:MybatisPlus的注解,标识表名
  • @TableId:标识主键,设置主键增长类型
  • @TableField:标识表字段

mapper和映射文件

mapper 接口代码:

package com.zl.model.repo;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zl.model.entity.TSystemMysqlBackups;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

@Mapper
public interface TSystemMysqlBackupsRepo extends BaseMapper<TSystemMysqlBackups> {
    /**
     * 查询所有备份数据
     */
    List<TSystemMysqlBackups> selectBackupsList();

    /**
     * 根据ID查询
     */
    TSystemMysqlBackups selectListId(@Param("id") Long id);
}

映射文件代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.zl.model.repo.TSystemMysqlBackupsRepo">
    <resultMap id="Base_Result_Map" type="com.zl.model.entity.TSystemMysqlBackups">
        <id column="id" property="id"/>
        <result column="mysql_ip" property="mysqlIp"/>
        <result column="mysql_port" property="mysqlPort"/>
        <result column="mysql_cmd" property="mysqlCmd"/>
        <result column="mysql_back_cmd" property="mysqlBackCmd"/>
        <result column="database_name" property="databaseName"/>
        <result column="backups_path" property="backupsPath"/>
        <result column="backups_name" property="backupsName"/>
        <result column="operation" property="operation"/>
        <result column="status" property="status"/>
        <result column="recovery_time" property="recoveryTime"/>
        <result column="create_time" property="createTime"/>
    </resultMap>

    <sql id="Base_Column_List">
        id
        as id,
        `mysql_ip` as mysqlIp,
        `mysql_port` as mysqlPort,
        `mysql_cmd` as mysqlCmd,
        `mysql_back_cmd` as mysqlBackCmd,
        `database_name` as databaseName,
        `backups_path` as backupsPath,
        `backups_name` as backupsName,
        `operation` as operation,
        `status` as status,
        `recovery_time` as recoveryTime,
        `create_time` as createTime
    </sql>

    <select id="selectListId" resultMap="Base_Result_Map">
        SELECT *
        FROM `t_mysql_backups`
        WHERE `status` != 0
          AND id = #{id}
    </select>

    <select id="selectBackupsList" resultMap="Base_Result_Map">
        SELECT *
        FROM `t_mysql_backups`
        WHERE `status` != 0
        ORDER BY create_time DESC
    </select>

</mapper>

Service 接口和实现类

service 接口

package com.zl.domain.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.zl.model.entity.TSystemMysqlBackups;

import java.util.List;

public interface TSystemMysqlBackupsService extends IService<TSystemMysqlBackups> {
    /**
     * 查询最新的表备份
     */
    TSystemMysqlBackups selectBackupOne(String tableName);

    /**
     * 查询所有备份数据
     */
    List<TSystemMysqlBackups> selectBackupsList();

    /**
     * mysql备份库接口
     */
    Object mysqlBackupDatabase(String filePath, String url, String userName, String password);


    /**
     * mysql备份表接口
     */
    List<Object> mysqlBackupTables(String filePath, String url, String userName, String password, String[] tables);

    /**
     * 根据ID查询
     */
    TSystemMysqlBackups selectListId(Long id);

    /**
     * 恢复数据库
     *
     * @param smb      恢复对象
     * @param userName 数据库用户名
     * @param password 数据库密码
     * @return
     */
    Object rollback(TSystemMysqlBackups smb, String userName, String password);

    /**
     * sql脚本文件恢复数据库
     *
     * @param smb 恢复对象
     * @param conn 数据库连接
     * @return
     */
    Object rollbackFile(TSystemMysqlBackups smb, Connection conn);

}

实现类:

package com.zl.domain.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zl.model.entity.TSystemMysqlBackups;
import com.zl.model.repo.TSystemMysqlBackupsRepo;
import com.zl.domain.service.TSystemMysqlBackupsService;
import com.zl.utils.Constants;
import com.zl.utils.Result;
import org.apache.ibatis.io.Resources;
import com.its.server.utils.UnzipUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.apache.ibatis.jdbc.ScriptRunner;

import javax.annotation.Resource;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.sql.Connection;

@Slf4j
@Service
public class TSystemMysqlBackupsServiceImpl extends ServiceImpl<TSystemMysqlBackupsRepo, TSystemMysqlBackups> implements TSystemMysqlBackupsService {
    @Resource
    private TSystemMysqlBackupsRepo tSystemMysqlBackupsRepo;

    /**
     * 查询最新的表备份
     */
    @Override
    public TSystemMysqlBackups selectBackupOne(String tableName) {
        // 获取最新的备份
        TSystemMysqlBackups tSystemMysqlBackups = tSystemMysqlBackupsRepo.selectOne(new QueryWrapper<TSystemMysqlBackups>().eq("table_name", tableName).orderByDesc("create_time").last("limit 1"));
        return tSystemMysqlBackups;
    }

    @Override
    public List<TSystemMysqlBackups> selectBackupsList() {
        return tSystemMysqlBackupsRepo.selectBackupsList();
    }

    @Override
    public Object mysqlBackupDatabase(String filePath, String url, String userName, String password) {
        // 清理备份数据 备份10天数据
        this.clearBackupData(10);
        
        List<String> urlInfo = this.getUrlInfo(url);
        if (urlInfo.size() != 3) {
            return Result.failed(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.value(), "备份失败,文件保存异常,请查看文件内容后重新尝试!");
        }
        // 获取ip
        final String ip = urlInfo.get(0);
        // 获取端口号
        final String port = urlInfo.get(1);
        // 获取数据库名称
        final String database_name = urlInfo.get(2);
        // 数据库文件名称
        StringBuilder mysqlFileName = new StringBuilder()
                .append(database_name)
                .append("_")
                .append(DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss"))
                .append(Constants.FILE_SUFFIX);
        // 备份命令
        StringBuilder cmd = new StringBuilder()
                .append("mysqldump ")
                // --skip-comments参数 导出没有 -- 注释,需要可以删掉
                .append("--skip-comments ")
                .append("--no-tablespaces ")
                .append("-h ")
                .append(ip)
                .append(" -P ")
                .append(port)
                .append(" -u")
                .append(userName)
                .append(" -p")
                .append(password)
                // 排除MySQL备份表
                .append(" --ignore-table ")
                .append(database_name)
                .append(".t_mysql_backups ")
                .append(database_name)
                .append(" > ")
                .append(filePath)
                .append(mysqlFileName);
        // 判断文件是否保存成功
        if (!FileUtil.exist(filePath)) {
            FileUtil.mkdir(filePath);
            return Result.failed(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.value(), "备份失败,文件保存异常,请查看文件内容后重新尝试!");
        }
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        String[] command = new String[0];
        if (Constants.isSystem(osName)) {
            // Windows
            command = new String[]{"cmd", "/c", String.valueOf(cmd)};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(cmd)};
        }
        TSystemMysqlBackups smb = new TSystemMysqlBackups();
        // 备份信息存放到数据库
        smb.setMysqlIp(ip);
        smb.setMysqlPort(port);
        smb.setBackupsName(String.valueOf(mysqlFileName));
        smb.setDatabaseName(database_name);
        smb.setMysqlCmd(String.valueOf(cmd));
        smb.setBackupsPath(filePath);
        smb.setCreateTime(DateTime.now());
        smb.setStatus(1);
        smb.setTableName(table);
        smb.setOperation(0);
        // 获取Runtime实例
        Process process = null;
        log.info("数据库备份命令为:{}", cmd);
        try {
            process = Runtime.getRuntime().exec(command);
            if (process.waitFor() == 0) {
                log.info("Mysql 数据库备份成功,备份文件名:{}", mysqlFileName);
                tSystemMysqlBackupsRepo.insert(smb);
                // 清理 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 注释
                this.clearSqlAnnotation(filePath + mysqlFileName);
            } else {
                return Result.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "网络异常,数据库备份失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "网络异常,数据库备份失败");
        }
        return smb;
    }

    @Override
    public List<Object> mysqlBackupTables(String filePath, String url, String userName, String password, String[] tables) {
        // 清理备份数据 备份10天数据
        this.clearBackupData(10);
        List<String> urlInfo = this.getUrlInfo(url);
        // 返回备份数据信息
        List<Object> list = new ArrayList<>(0);
        if (urlInfo.size() != 3) {
            list.add(Result.failed(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.value(), "备份失败,文件保存异常,请查看文件内容后重新尝试!"));
            return list;
        }
        // 获取ip
        final String ip = urlInfo.get(0);
        // 获取端口号
        final String port = urlInfo.get(1);
        // 获取数据库名称
        final String database_name = urlInfo.get(2);
        // 数据库文件名称
        for (String table : tables) {
            StringBuilder mysqlFileName = new StringBuilder()
                    .append(database_name)
                    .append("_")
                    .append(table)
                    .append("_")
                    .append(DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss"))
                    .append(Constants.FILE_SUFFIX);
            // 备份命令
            StringBuilder cmd = new StringBuilder()
                    .append("mysqldump ")
                    // --skip-comments参数 导出没有 -- 注释,需要可以删掉
                    .append("--skip-comments ")
                    .append("-h ")
                    .append(ip)
                    .append(" -P ")
                    .append(port)
                    .append(" -u")
                    .append(userName)
                    .append(" -p")
                    .append(password)
                    .append(" " + database_name)
                    .append(" " + table)
                    .append(" > ")
                    .append(filePath)
                    .append(mysqlFileName);
            // 判断文件是否保存成功
            if (!FileUtil.exist(filePath)) {
                FileUtil.mkdir(filePath);
                list.add(Result.failed(HttpStatus.REQUEST_HEADER_FIELDS_TOO_LARGE.value(), "备份失败,文件保存异常,请查看文件内容后重新尝试!"));
            }
            // 获取操作系统名称
            String osName = System.getProperty("os.name").toLowerCase();
            String[] command = new String[0];
            if (Constants.isSystem(osName)) {
                // Windows
                command = new String[]{"cmd", "/c", String.valueOf(cmd)};
            } else {
                // Linux
                command = new String[]{"/bin/sh", "-c", String.valueOf(cmd)};
            }
            TSystemMysqlBackups smb = new TSystemMysqlBackups();
            // 备份信息存放到数据库
            smb.setMysqlIp(ip);
            smb.setMysqlPort(port);
            smb.setBackupsName(String.valueOf(mysqlFileName));
            smb.setDatabaseName(database_name);
            smb.setMysqlCmd(String.valueOf(cmd));
            smb.setBackupsPath(filePath);
            smb.setCreateTime(DateTime.now());
            smb.setStatus(1);
            smb.setOperation(0);
            // 获取Runtime实例
            Process process = null;
            log.info("数据库备份命令为:{}", cmd);
            try {
                process = Runtime.getRuntime().exec(command);
                if (process.waitFor() == 0) {
                    log.info("Mysql 数据库备份成功,备份文件名:{}", mysqlFileName);
                    tSystemMysqlBackupsRepo.insert(smb);
                    // 清理 /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 注释
                    this.clearSqlAnnotation(filePath + mysqlFileName);
                } else {
                    list.add(Result.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "网络异常,数据库备份失败"));
                }
            } catch (Exception e) {
                e.printStackTrace();
                list.add(Result.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "网络异常,数据库备份失败"));
            }
            list.add(smb);
        }
        return list;
    }

    @Override
    public TSystemMysqlBackups selectListId(Long id) {
        return tSystemMysqlBackupsRepo.selectListId(id);
    }

    @Override
    public Object rollback(TSystemMysqlBackups smb, String userName, String password) {
        // 备份路径和文件名
        StringBuilder realFilePath = new StringBuilder().append(smb.getBackupsPath()).append(smb.getBackupsName());
        if (!FileUtil.exist(String.valueOf(realFilePath))) {
            return Result.failed(HttpStatus.NOT_FOUND.value(), "文件不存在,恢复失败,请查看目录内文件是否存在后重新尝试!");
        }
        StringBuilder cmd = new StringBuilder()
                .append("mysql -h")
                .append(smb.getMysqlIp())
                .append(" -u")
                .append(userName)
                .append(" -p")
                .append(password)
                .append(" ")
                .append(smb.getDatabaseName())
                .append(" < ")
                .append(realFilePath);
        String[] command = new String[0];
        log.error("数据库恢复命令为:{}", cmd);
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        if (Constants.isSystem(osName)) {
            // Windows
            command = new String[]{"cmd", "/c", String.valueOf(cmd)};
        } else {
            // Linux
            command = new String[]{"/bin/sh", "-c", String.valueOf(cmd)};
        }
        // 恢复指令写入到数据库
        smb.setMysqlBackCmd(String.valueOf(cmd));
        // 更新操作次数
        smb.setRecoveryTime(DateTime.now());
        smb.setOperation(smb.getOperation() + 1);
        // 获取Runtime实例
        Process process = null;
        try {
            process = Runtime.getRuntime().exec(command);
            if (process.waitFor() == 0) {
                tSystemMysqlBackupsRepo.updateById(smb);
                log.info("Mysql 数据库恢复成功,恢复文件名:{}", realFilePath);
            } else {
                return Result.failed(HttpStatus.GATEWAY_TIMEOUT.value(), "网络异常,恢复失败,请稍后重新尝试!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Result.failed(HttpStatus.GATEWAY_TIMEOUT.value(), "网络异常,恢复失败,请稍后重新尝试!");
        }
        return smb;
    }

    /**
     * sql脚本文件恢复数据库
     *
     * @param smb  恢复对象
     * @param conn 数据库连接
     * @return
     */
    @Override
    public Object rollbackFile(TSystemMysqlBackups smb, Connection conn) {
        try {
            StringBuilder realFilePath = new StringBuilder().append(smb.getBackupsPath()).append(smb.getBackupsName());
            if (!FileUtil.exist(String.valueOf(realFilePath))) {
                return Result.failed(HttpStatus.NOT_FOUND.value(), "文件不存在,恢复失败,请查看目录内文件是否存在后重新尝试!");
            }
            // 创建ScriptRunner,用于执行SQL脚本
            ScriptRunner runner = new ScriptRunner(conn);
            runner.setErrorLogWriter(null);
            runner.setLogWriter(null);
            // 遇到错误回滚
            runner.setStopOnError(true);
            Resources.setCharset(Charset.forName("UTF-8"));
            // 执行SQL脚本
            runner.runScript(new InputStreamReader(new FileInputStream(realFilePath.toString()), "UTF-8"));
            // 关闭连接
            conn.close();
            // 恢复指令写入到数据库
            smb.setMysqlBackCmd("执行sql文件");
            // 更新操作次数
            smb.setRecoveryTime(DateTime.now());
            smb.setOperation(smb.getOperation() + 1);
            tSystemMysqlBackupsRepo.updateById(smb);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("sql执行失败", e);
        }
        return smb;
    }

    /**
     * 清理sql文件里面的注释
     * 例如: !40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT
     * windows 需要安装 sed-windows 包
     *
     * @param fileNamePath 文件路径
     */
    private void clearSqlAnnotation(String fileNamePath) {
        // 判断文件是否存在
        if (FileUtil.exist(fileNamePath)) {
            // 清理注释命令
            StringBuilder cmd = new StringBuilder()
                    .append("sed -i '/^\\//d' ")
                    .append(fileNamePath);
            // 获取操作系统名称
            String osName = System.getProperty("os.name").toLowerCase();
            String[] command = new String[0];
            if (Constants.isSystem(osName)) {
                // Windows
                command = new String[]{"cmd", "/c", String.valueOf(cmd)};
            } else {
                // Linux
                command = new String[]{"/bin/sh", "-c", String.valueOf(cmd)};
            }
            Process process = null;
            try {
                process = Runtime.getRuntime().exec(command);
                if (process.waitFor() == 0) {
                    log.info("备份sql文件清理注释成功,文件:" + fileNamePath);
                } else {
                    log.info("备份sql文件清理注释失败,文件:" + fileNamePath);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 获取ip,端口号,数据库名信息
     *
     * @param url 连接url地址 eg:jdbc:mysql://192.168.32.13:3306/my_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
     * @return ip,端口号,数据库名信息
     */
    private List<String> getUrlInfo(String url) {
        List<String> list = new ArrayList<>(0);
        String[] split = url.split("/");
        if (split.length > 2) {
            String[] hostAndPort = split[2].split(":");
            if (hostAndPort.length > 1) {
                list.add(hostAndPort[0]);
                list.add(hostAndPort[1]);
            }
            String[] database = split[3].split("\\?");
            if (database.length > 1) {
                list.add(database[0]);
            }
        }
        return list;
    }

    /**
     * 保留几天的日志
     */
    private void clearBackupData(Integer day) {
        int num = 0 - day;
        String time = LocalDateTime.now().plusDays(num).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        List<TSystemMysqlBackups> tSystemMysqlBackups = tSystemMysqlBackupsRepo.selectList(new QueryWrapper<TSystemMysqlBackups>().apply("DATE_FORMAT(create_time,'%Y-%m-%d') < {0}", time));
        for (TSystemMysqlBackups tSystemMysqlBackup : tSystemMysqlBackups) {
            StringBuilder sb = new StringBuilder().append(tSystemMysqlBackup.getBackupsPath()).append(tSystemMysqlBackup.getBackupsName());
            File file = new File(String.valueOf(sb));
            // 删除文件
            Constants.deleteDir(file);
            // 删除数据
            tSystemMysqlBackupsRepo.deleteById(tSystemMysqlBackup.getId());
        }
    }
}

工具类

package com.zl.utils;

public class Constants {
    /**
     * 文件后缀
     */
    public static final String FILE_SUFFIX = ".sql";

    /**
     * 判断操作系统类型、Linux|Windows
     */
    public static boolean isSystem(String osName) {
        Boolean flag = null;
        if (osName.startsWith("windows")) {
            flag = true;
        } else if (osName.startsWith("linux")) {
            flag = false;
        }
        return flag;
    }

}

   /**
     * 递归删除目录及文件
     */
    public static void deleteDir(File file) {
        // 结束递归循环
        if (!file.exists()) {
            return;
        }
        // 如果是目录,请进入内部并递归调用
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                // 调用递归
                deleteDir(f);
            }
        }
        // 调用delete删除文件和空目录
        file.delete();
    }

注释的含义/*!后面的数字,其实就是mysql版本号信息,意思是当版本号高于或者等于注释里的版本号时,里面的set命令才会被执行

例如:/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

1)40101,这是mysql版本号,该数字告诉我们这些语句只有在大于或等于该版本的mysql中才能执行,即在mysql4.01.01及以上版本的mysql中执行

2)set 语句是将当前系统变量CHARACTER_SET_CLIENT的值赋给OLD_CHARACTER_SET_CLIENT

出现导入错误:/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */

解决:使用sed命令,将SQL中的注释行去掉,再执行

sed -i '/^\//d' 文件名.sql

package com.zl.utils;


import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;

@ApiModel(
        description = "统一应答协议"
)
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("业务代码")
    private Integer code;
    @ApiModelProperty("消息")
    private String msg;
    @ApiModelProperty("系统时间")
    private String sysTime;
    @ApiModelProperty("数据")
    private T data;

    private Result() {
    }

    public static IPage getPage(Integer pageNumber, Integer pageSize, List list) {
        IPage page = new Page<>(pageNumber, pageSize, list.size()).setRecords(ListUtil.page(pageNumber - 1, pageSize, list));
        return page;
    }

    public static <T> Result<T> ok() {
        return doInstance(ResultsCode.SUCCESS.CODE, ResultsCode.SUCCESS.MSG);
    }

    public static <T> Result<T> ok(T o) {
        Result<T> result = ok();
        result.setData(o);
        return result;
    }

    public static <T> Result<T> ok(T o, int code, String msg) {
        Result<T> ok = ok(o);
        ok.setCode(code);
        ok.setMsg(msg);
        return ok;
    }

    public static <T> Result<T> ok(int code, String msg) {
        Result<T> ok = ok();
        ok.setCode(code);
        ok.setMsg(msg);
        return ok;
    }

    public static <T> Result<T> failed() {
        return doInstance(ResultsCode.FAILED.CODE, ResultsCode.FAILED.MSG);
    }

    public static <T> Result<T> failed(T o, int code, String msg) {
        Result<T> failed = doInstance(code, msg);
        failed.setData(o);
        return failed;
    }

    public static <T> Result<T> failed(int code, String msg) {
        Result<T> failed = failed();
        failed.setCode(code);
        failed.setMsg(msg);
        return failed;
    }

    public static <T> Result<T> failed(String msg) {
        Result<T> failed = failed();
        failed.setMsg(msg);
        return failed;
    }

    private static <T> Result<T> doInstance(int code, String msg) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        String now = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        result.setSysTime(now);
        result.setData(new HashMap(0));
        return result;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void setSysTime(String sysTime) {
        this.sysTime = sysTime;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Integer getCode() {
        return this.code;
    }

    public String getMsg() {
        return this.msg;
    }

    public String getSysTime() {
        return this.sysTime;
    }

    public T getData() {
        return this.data;
    }

    @Override
    public String toString() {
        return "Result(code=" + this.getCode() + ", msg=" + this.getMsg() + ", sysTime=" + this.getSysTime() + ", data=" + this.getData() + ")";
    }

    public enum ResultsCode {
        SUCCESS(200, "执行成功"),
        FAILED(500, "执行失败"),
        NOT_FOUND(404, "资源找不到"),
        DATA_REPEAT(409, "数据重复");

        public int CODE;
        public String MSG;

        private ResultsCode(int code, String msg) {
            this.CODE = code;
            this.MSG = msg;
        }

        /**
         * 根据code获取value
         */
        public static String getValue(int code) {
            for (ResultsCode resultsCode : values()) {
                if (code == resultsCode.CODE) {
                    return resultsCode.MSG;
                }
            }
            return "";
        }
    }
}

配置文件

spring:
  datasource:
    dynamic:
      primary: master
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://192.168.32.13:3306/my_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
          username: root
          password: test@123
          win-path: C:\
          linux-path: /work/backup/
        read:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://192.168.32.13:3306/my_test_new?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
          username: root
          password: test@123
          win-path: C:\
          linux-path: /work/backup/

定时器

package com.zl.quartz;

import com.zl.domain.service.TSystemMysqlBackupsService;
import com.zl.utils.Constants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Slf4j
public class GetOutDoorDataTask {
    @Resource
    private TSystemMysqlBackupsService tSystemMysqlBackupsService;


    /**
     * 数据库用户名
     */
    @Value("${spring.datasource.dynamic.datasource.master.username}")
    private String userName;

    /**
     * 数据库密码
     */
    @Value("${spring.datasource.dynamic.datasource.master.password}")
    private String password;

    /**
     * 数据库url
     */
    @Value("${spring.datasource.dynamic.datasource.master.url}")
    private String url;

    /**
     * Windows数据库备份地址
     */
    @Value("${spring.datasource.dynamic.datasource.master.win-path}")
    private String windowsPath;

    /**
     * Linux数据库备份地址
     */
    @Value("${spring.datasource.dynamic.datasource.master.linux-path}")
    private String linuxPath;

    /**
     * 每天凌晨4点备份
     */
    @Scheduled(cron = "0 0 4 * * ?")
    public void testData() {
        String path = null;
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        if (Constants.isSystem(osName)) {
            // Windows
            path = this.windowsPath;
        } else {
            // Linux
            path = this.linuxPath;
        }
        // 数据库用户名
        String userName = this.userName;
        // 数据库密码
        String password = this.password;
        // 数据库地址
        String url = this.url;
        // 备份指定表
        String[] tables = new String[]{"t_sys_user", "t_sys_user_dept", "t_sys_dept"};
        List<Object> list = tSystemMysqlBackupsService.mysqlBackupTables(path, url, userName, password, tables);
        for(Object one : list){
          if(one instanceof Result){
            log.info(((Result)one).getMsg());
          }
        }
    }
}

控制器

import com.zl.utils.Constants;
import com.zl.utils.Result;
import com.zl.domain.service.TSystemMysqlBackupsService;
import com.zl.model.entity.TSystemMysqlBackups;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.zl.dto.DatabaseConfig;
 
import java.util.List;
import java.util.Map;
import java.sql.Connection;

/**
 * 类描述: MySQL数据备份接口
 */
@RestController
@Api(description = "MySQL数据备份")
@RequestMapping(value = "/api/system/baskups")
public class SystemMysqlBackupsController {
 
    @Autowired
    private TSystemMysqlBackupsService tSystemMysqlBackupsService;

   /**
     * 数据库用户名
     */
    @Value("${spring.datasource.dynamic.datasource.master.username}")
    private String userName;

    /**
     * 数据库密码
     */
    @Value("${spring.datasource.dynamic.datasource.master.password}")
    private String password;

    /**
     * 数据库url
     */
    @Value("${spring.datasource.dynamic.datasource.master.url}")
    private String url;

    /**
     * Windows数据库备份地址
     */
    @Value("${spring.datasource.dynamic.datasource.master.win-path}")
    private String windowsPath;

    /**
     * Linux数据库备份地址
     */
    @Value("${spring.datasource.dynamic.datasource.master.linux-path}")
    private String linuxPath;

    @Resource(name = "databaseConfigOne")
    private DatabaseConfig databaseConfigOne;
    @Resource(name = "databaseConnection1")
    private Connection connection1;
 
    @ApiOperation("备份测试数据")
    @GetMapping("/backDatabaseTable")
    public Result backDatabaseTable() {
        // 数据库用户名
        String userName = databaseConfigOne.getUserName();
        // 数据库密码
        String password = databaseConfigOne.getPassword();
        String path = null;
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        if (Constants.isSystem(osName)) {
            // Windows
            path = databaseConfigOne.getWindowsPath();
        } else {
            // Linux
            path = databaseConfigOne.getLinuxPath();
        }
        // 数据库地址
        String url = databaseConfigOne.getUrl();
        String[] tables = new String[]{"t_test"};
        tSystemMysqlBackupsService.mysqlBackupTables(path, url, userName, password, tables, null);
        return Result.ok();
    }

    @ApiOperation("恢复备份测试数据")
    @GetMapping("/rollbackData")
    public Result rollbackData() {
        TSystemMysqlBackups one = tSystemMysqlBackupsService.selectBackupOne("t_test");
        tSystemMysqlBackupsService.rollbackFile(one, connection1);
        return Result.ok();
    }

    @ApiOperation(value = "获取所有备份数据列表")
    @GetMapping("/backupsList")
    public Object backupsList() {
        List<TSystemMysqlBackups> systemMysqlBackups = tSystemMysqlBackupsService.selectBackupsList();
        return Result.ok(systemMysqlBackups);
    }
 
    @ApiOperation(value = "MySQL备份")
    @PostMapping("/mysqlBackups")
    public Object mysqlBackups() {
        String path = null;
        // 获取操作系统名称
        String osName = System.getProperty("os.name").toLowerCase();
        if (Constants.isSystem(osName)) {
            // Windows
            path = this.windowsPath;
        } else {
            // Linux
            path = this.linuxPath;
        }
        // 数据库用户名
        String userName = this.userName;
        // 数据库密码
        String password = this.password;
        // 数据库地址
        String url = this.url;
        // 调用备份
        Object systemMysqlBackups = tSystemMysqlBackupsService.mysqlBackupDatabase(path, url, userName, password);
        return Result.ok(systemMysqlBackups);
    }
 
    @ApiOperation(value = "恢复数据库")
    @PutMapping("/rollback")
    public Object rollback(@RequestBody Map<String, Object> map) {
        Long id = Long.valueOf(map.get("id").toString());
        if (id == null) {
            return Result.failed(HttpStatus.INTERNAL_SERVER_ERROR.value(), "id不能为null,请重新尝试!");
        }
        // 数据库用户名
        String userName = this.userName;
        // 数据库密码
        String password = this.password;
        // 根据id查询查询已有的信息
        TSystemMysqlBackups smb = tSystemMysqlBackupsService.selectListId(id);
        // 恢复数据库
        Object rollback = tSystemMysqlBackupsService.rollback(smb, userName, password);

        return Result.ok(rollback);
    }
}

封装参数

package zl.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * 数据库配置
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DatabaseConfig {
    /**
     * 数据库url
     */
    private String url;
    /**
     * 数据库用户名
     */
    private String userName;
    /**
     * 数据库密码
     */
    private String password;
    /**
     * Windows数据库备份地址
     */
    private String windowsPath;
    /**
     * Linux数据库备份地址
     */
    private String linuxPath;
}
package com.zl.config;

import com.zl.dto.DatabaseConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import java.sql.Connection;
import java.sql.DriverManager;

@Configuration
public class DatabaseBackupConfig {
    /**
     * 数据库用户名
     */
    @Value("${spring.datasource.dynamic.datasource.master.username}")
    private String userName;

    /**
     * 数据库密码
     */
    @Value("${spring.datasource.dynamic.datasource.master.password}")
    private String password;

    /**
     * 数据库url
     */
    @Value("${spring.datasource.dynamic.datasource.master.url}")
    private String url;
    /**
     * 数据库url
     */
    @Value("${spring.datasource.dynamic.datasource.read.url}")
    private String url1;

    /**
     * Windows数据库备份地址
     */
    @Value("${spring.datasource.dynamic.datasource.master.win-path}")
    private String windowsPath;

    /**
     * Linux数据库备份地址
     */
    @Value("${spring.datasource.dynamic.datasource.master.linux-path}")
    private String linuxPath;

    @Bean(name = "databaseConfigOne")
    public DatabaseConfig getDatabaseConfigOne() {
        DatabaseConfig databaseConfigOne = new DatabaseConfig();
		// 可以将属性改为 ip、port、databaseName,不使用截取
        databaseConfigOne.setUrl(url);
        databaseConfigOne.setUserName(userName);
        databaseConfigOne.setPassword(password);
        databaseConfigOne.setLinuxPath(linuxPath);
        databaseConfigOne.setWindowsPath(windowsPath);
        return databaseConfigOne;
    }

    @Bean(name = "databaseConfigTwo")
    public DatabaseConfig getDatabaseConfigTwo() {
        DatabaseConfig databaseConfigTwo = new DatabaseConfig();
        databaseConfigTwo.setUrl(url1);
        databaseConfigTwo.setUserName(userName);
        databaseConfigTwo.setPassword(password);
        databaseConfigTwo.setLinuxPath(linuxPath);
        databaseConfigTwo.setWindowsPath(windowsPath);
        return databaseConfigTwo;
    }

    @Bean("databaseConnection1")
    public Connection getConnection1() {
        Connection conn = null;
        try {
            // 建立连接
            conn = DriverManager.getConnection(url, userName, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    @Bean("databaseConnection2")
    public Connection getConnection2() {
        Connection conn = null;
        try {
            // 建立连接
            conn = DriverManager.getConnection(url1, userName, password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }
}

结果:

数据库备份与恢复命令

备份:从数据库导出数据

$ mysqldump -h 链接 ip -P( 大写 ) 端口 -u 用户名 -p 密码数据库名 > xxxx.sql(路径)

示例:mysqldump -h127.0.0.1 -P3307 -uroot -p8888 test > test.sql;

1、导出数据和表结构——将特定数据库特定表中的数据和表格结构和数据全部返回

$ mysqldump -uroot -h127.0.0.1 -padmin -P3306 test up_subjects > test.sql

2、导出表结构却不导出表数据——只返回特定数据库特定表格的表格结构,不返回数据, 添加“-d”命令参数

$ mysqldump -uroot -h127.0.0.1 -padmin -P3306 -d test up_subjects > test.sql

3、导出表结构和满足挑顶条件的表数据——只返回特定数据库中特定表的表格结构和满足特定条件的数据

$ mysqldump -uroot -h127.0.0.1 -padmin -P3306 test up_subjects --where="ctime>'2017-01-01'and ctime<'2017-06-30'" >test.sql

eg: 导出表的100条数据
mysqldump -uroot -p -h127.0.0.1 test up_subjects --where="true limit 100" > ./test.sql

3、导出数据却不导出表结构——只返回特定数据库中特定表格的数据,不返回表格结构,添加“-t”命令参数

$ mysqldump -uroot -h127.0.0.1 -padmin -t -P3306 test up_subjects >test.sql

5、导出特定数据库的所有表格的表结构及其数据,添加“–databases ”命令参数

$ mysqldump -uroot -h127.0.0.1 -padmin -P3306 --databases test > test.sql

恢复导入数据库数据

将导出的本地文件导入到指定数据库

1、系统命令行

# 格式:mysql -h 链接 ip -P(大写)端口 -u 用户名 -p 密码 数据库名 < d:XX.sql(路劲) 
$ mysql -uusername -ppassword test < test.sql

2、或 mysql 命令行

mysql>
# 选择数据库
user test;
# 导入 sql
source test.sql;

3、恢复整个数据库的方法

$ mysql -uroot -h127.0.0.1 -padmin -P3306 < test.sql

具体恢复示例

1、先登录该 MySQL 服务器,切换要导入数据的数据、具体命令如下

mysql> use test;

mysql> source /home/test/test.sql

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 9 rows affected (0.00 sec)

Records: 9 Duplicates: 0  Warnings: 0

注释:表示影响的记录为 9 行,重复的记录有 0 行,警告的记录有 0 个

2、直接使用系统命令行

$ mysql -uroot -h127.0.0.1 -padmin -P3306 test < /home/test/test.sql

mysqldump 参数说明

mysqldump客户端可用来转储数据库或搜集数据库进行备份或将数据转移到另一个 sql 服务器 (不一定是一个mysql 服务器)。转储包含创建表和 / 或装载表的 sql 语句。

如果在服务器上进行备份,并且表均为 myisam 表,应考虑使用mysqlhotcopy,因为可以更快地进行备份和恢复。

参数 命令 说明
--help mysqldump --help 显示帮助信息并退出
--all-databases , -A mysqldump -uroot -p --all-databases 导出全部数据库
--all-tablespaces , -Y mysqldump -uroot -p --all-databases --all-tablespaces 导出全部表空间
--no-tablespaces , -y mysqldump -uroot -p --all-databases --no-tablespaces 不导出任何表空间信息
--add-drop-database mysqldump -uroot -p --all-databases --add-drop-database 每个数据库创建之前添加 drop 数据库语句
--add-drop-table # (默认添加 drop 语句) $ mysqldump -uroot -p --all-databases # (取消 drop 语句) $ mysqldump -uroot -p --all-databases --skip-add-drop-table 每个数据表创建之前添加 drop 数据表语句。(默认为打开状态,使用 --skip-add-drop-table 取消选项)
--add-locks # (默认添加 LOCK 语句) $ mysqldump -uroot -p --all-databases # (取消 LOCK 语句) $ mysqldump -uroot -p --all-databases --skip-add-locks 在每个表导出之前增加 LOCK TABLES 并且之后 UNLOCK TABLE。(默认为打开状态,使用--skip-add-locks 取消选项)
--allow-keywords mysqldump -uroot -p --all-databases --allow-keywords 允许创建是关键词的列名字。这由表名前缀于每个列名做到
--apply-slave-statements mysqldump -uroot -p --all-databases --apply-slave-statements 'CHANGE MASTER' 前添加'STOP SLAVE',并且在导出的最后添加'START SLAVE'
--character-sets-dir mysqldump -uroot -p --all-databases --character-sets-dir=/usr/local/mysql/share/mysql/charsets 字符集文件的目录
--comments # (默认记录注释) $ mysqldump -uroot -p --all-databases # (取消注释) $ mysqldump -uroot -p --all-databases --skip-comments 附加注释信息。默认为打开,可以用 --skip-comments 取消
--compatible mysqldump -uroot -p --all-databases --compatible=ansi 导出的数据将和其它数据库或旧版本的 MySQL 相兼容。值可以为 ansi、mysql323、mysql40、postgresql、oracle、mssql、db2、maxdb、no_key_options、no_tables_options、no_field_options 等,要使用几个值,用逗号将它们隔开。它并不保证能完全兼容,而是尽量兼容
--compact mysqldump -uroot -p --all-databases --compact 导出更少的输出信息(用于调试)。去掉注释和头尾等结构。可以使用选项:--skip-add-drop-table --skip-add-locks --skip-comments --skip-disable-keys
--complete-insert, -c mysqldump -uroot -p --all-databases --complete-insert 使用完整的 insert 语句 (包含列名称)。这么做能提高插入效率,但是可能会受到max_allowed_packet 参数的影响而导致插入失败
--compress, -C mysqldump -uroot -p --all-databases --compress 在客户端和服务器之间启用压缩传递所有信息
--create-options, -a mysqldump -uroot -p --all-databases CREATE TABLE 语句中包括所有 MySQL 特性选项。(默认为打开状态)
--databases, -B mysqldump -uroot -p --databases test mysql 导出几个数据库。参数后面所有名字参量都被看作数据库名
--debug $ mysqldump -uroot -p --all-databases --debug # 默认值 $ mysqldump -uroot -p --all-databases --debug=" d:t,/tmp/debug.trace" 输出 debug 信息,用于调试。默认值为:d:t,/tmp/mysqldump.trace
--debug-check mysqldump -uroot -p --all-databases --debug-check 检查内存和打开文件使用说明并退出
--debug-info mysqldump -uroot -p --all-databases --debug-info 输出调试信息并退出
--default-character-set mysqldump -uroot -p --all-databases --default-character-set=utf8 设置默认字符集,默认值为utf8
--delayed-insert mysqldump -uroot -p --all-databases --delayed-insert 采用延时插入方式(INSERT DELAYED)导出数据
--delete-master-logs mysqldump -uroot -p --all-databases --delete-master-logs master备份后删除日志. 这个参数将自动激活--master-data
--disable-keys $ mysqldump -uroot -p --all-databases 对于每个表,用 /*!40000 ALTER TABLE tbl_name DISABLE KEYS /; 和 /!40000ALTER TABLE tbl_name ENABLE KEYS */; 语句引用 INSERT 语句。这样可以更快地导入 dump 出来的文件,因为它是在插入所有行后创建索引的。该选项只适合 MyISAM 表,默认为打开状态
--dump-slave $ mysqldump -uroot -p --all-databases --dump-slave=1 $ mysqldump -uroot -p --all-databases --dump-slave=2 该选项将主的 binlog 位置和文件名追加到导出数据的文件中 (show slave status)。设置为1 时,将会以 CHANGE MASTER 命令输出到数据文件;设置为 2 时,会在 change 前加上注释。该选项将会打开 --lock-all-tables,除非--single-transaction 被指定。该选项会自动关闭 --lock-tables 选项。默认值为 0
--master-data $ mysqldump -uroot -p --host=localhost --all-databases --master-data=1; $ mysqldump -uroot -p --host=localhost --all-databases --master-data=2; 该选项将当前服务器的 binlog 的位置和文件名追加到输出文件中 (show master status)。如果为1,将会输出CHANGE MASTER 命令;如果为2,输出的CHANGE MASTER 命令前添加注释信息。该选项将打开 --lock-all-tables 选项,除非--single-transaction 也被指定(在这种情况下,全局读锁在开始导出时获得很短的时间;其他内容参考下面的 --single-transaction 选项)。该选项自动关闭 --lock-tables 选项
--events, -E mysqldump -uroot -p --all-databases --events 导出事件
--extended-insert, -e $ mysqldump -uroot -p --all-databases # (取消选项) $ mysqldump -uroot -p --all-databases--skip-extended-insert 使用具有多个 VALUES 列的 INSERT 语法。这样使导出文件更小,并加速导入时的速度。默认为打开状态,使用 --skip-extended-insert 取消选项
--fields-terminated-by mysqldump -uroot -p test test --tab=”/home/mysql” --fields-terminated-by="#" 导出文件中忽略给定字段。与 --tab 选项一起使用,不能用于 --databases--all-databases选项
--fields-enclosed-by mysqldump -uroot -p test test --tab=”/home/mysql” --fields-enclosed-by="#" 输出文件中的各个字段用给定字符包裹。与 --tab 选项一起使用,不能用于 --databases--all-databases选项
--fields-optionally-enclosed-by mysqldump -uroot -p test test --tab=”/home/mysql” --fields-enclosed-by=”#” --fields-optionally-enclosed-by ="#" 输出文件中的各个字段用给定字符选择性包裹。与 --tab 选项一起使用,不能用于 --databases--all-databases选项
--fields-escaped-by mysqldump -uroot -p mysql user --tab=”/home/mysql” --fields-escaped-by=”#” 输出文件中的各个字段忽略给定字符。与 --tab 选项一起使用,不能用于 --databases--all-databases选项
--flush-logs mysqldump -uroot -p --all-databases --flush-logs 开始导出之前刷新日志 请注意:假如一次导出多个数据库 (使用选项--databases 或者 --all-databases),将会逐个数据库刷新日志。除使用--lock-all-tables 或者 --master-data 外。在这种情况下,日志将会被刷新一次,相应的所以表同时被锁定。因此,如果打算同时导出和刷新日志应该使用 --lock-all-tables 或者 --master-data--flush-logs
--flush-privileges mysqldump -uroot -p --all-databases --flush-privileges 在导出 mysql 数据库之后,发出一条 FLUSH PRIVILEGES 语句。为了正确恢复,该选项应该用于导出 mysql 数据库和依赖 mysql 数据库数据的任何时候
--force mysqldump -uroot -p --all-databases --force 在导出过程中忽略出现的 SQL 错误
--hex-blob mysqldump -uroot -p --all-databases --hex-blob 使用十六进制格式导出二进制字符串字段。如果有二进制数据就必须使用该选项。影响到的字段类型有BINARY、VARBINARY、BLOB
--host, -h mysqldump -uroot -p --host=localhost --all-databases 需要导出的主机信息
--ignore-table mysqldump -uroot -p --host=localhost --all-databases --ignore-table=mysql.user 不导出指定表。指定忽略多个表时,需要重复多次,每次一个表。每个表必须同时指定数据库和表名。例如:--ignore-table=database.table1 --ignore-table=database.table2 ……
--include-master-host-port mysqldump -uroot -p --host=localhost --all-databases --include-master-host-port --dump-slave 产生的’CHANGE MASTER TO..‘语句中增加'MASTER_HOST=<host>,MASTER_PORT=<port>
--insert-ignore mysqldump -uroot -p --host=localhost --all-databases --insert-ignore 在插入行时使用 INSERT IGNORE 语句
--lines-terminated-by mysqldump -uroot -p --host=localhost test test --tab=”/tmp/mysql” --lines-terminated-by=”##” 输出文件的每行用给定字符串划分。与 --tab 选项一起使用,不能用于 --databases--all-databases选项
--lock-all-tables, -x mysqldump -uroot -p --host=localhost --all-databases --lock-all-tables 提交请求锁定所有数据库中的所有表,以保证数据的一致性。这是一个全局读锁,并且自动关闭 --single-transaction--lock-tables选项
--lock-tables, -l mysqldump -uroot -p --host=localhost --all-databases --lock-tables 开始导出前,锁定所有表。用 READ LOCAL 锁定表以允许 MyISAM 表并行插入。对于支持事务的表例如 InnoDBBDB--single-transaction是一个更好的选择,因为它根本不需要锁定表。 请注意当导出多个数据库时,--lock-tables分别为每个数据库锁定表。因此,该选项不能保证导出文件中的表在数据库之间的逻辑一致性。不同数据库表的导出状态可以完全不同
--log-error mysqldump -uroot -p --host=localhost --all-databases --log-error=/tmp/mysqldump_error_log.err 附加警告和错误信息到给定文件
--max_allowed_packet mysqldump -uroot -p --host=localhost --all-databases --max_allowed_packet=10240 服务器发送和接受的最大包长度
--net_buffer_length mysqldump -uroot -p --host=localhost --all-databases --net_buffer_length=1024 TCP/IPsocket 连接的缓存大小
--no-autocommit mysqldump -uroot -p --host=localhost --all-databases --no-autocommit 使用 autocommit/commit 语句包裹表
--no-create-db, -n mysqldump -uroot -p --host=localhost --all-databases --no-create-db 只导出数据,而不添加 CREATE DATABASE 语句
--no-create-info, -t mysqldump -uroot -p --host=localhost --all-databases --no-create-info 只导出数据,而不添加 CREATE TABLE 语句
--no-data, -d mysqldump -uroot -p --host=localhost --all-databases --no-data 不导出任何数据,只导出数据库表结构
--no-set-names, -N mysqldump -uroot -p --host=localhost --all-databases --no-set-names 等同于--skip-set-charset
--opt mysqldump -uroot -p --host=localhost --all-databases --opt 等同于 --add-drop-table, --add-locks, --create-options, --quick, --extended-insert,--lock-tables, --set-charset,--disable-keys 该选项默认开启, 可以用--skip-opt 禁用
--order-by-primary mysqldump -uroot -p --host=localhost --all-databases --order-by-primary 如果存在主键,或者第一个唯一键,对每个表的记录进行排序。在导出 MyISAM 表到 InnoDB 表时有效,但会使得导出工作花费很长时间
--password, -p mysqldump -uroot -p123 连接数据库密码
--pipe(windows 系统可用) mysqldump -uroot -p --host=localhost --all-databases --pipe 使用命名管道连接mysql
--port, -P # 注意是大写 P $ mysqldump -uroot -P3306 -p123 连接数据库端口号
--protocol mysqldump -uroot -p --host=localhost --all-databases --protocol=tcp 使用的连接协议,包括:tcp, socket, pipe, memory
--quick, -q $ mysqldump -uroot -p --host=localhost --all-databases $ mysqldump -uroot -p --host=localhost --all-databases --skip-quick 不缓冲查询,直接导出到标准输出。默认为打开状态,使用 --skip-quick 取消该选项
--quote-names,-Q $ mysqldump -uroot -p --host=localhost --all-databases $ mysqldump -uroot -p --host=localhost --all-databases --skip-quote-names 使用()引起表和列名。默认为打开状态,使用–skip-quote-names` 取消该选项
--replace mysqldump -uroot -p --host=localhost --all-databases --replace 使用REPLACE INTO 取代INSERT INTO
--result-file, -r mysqldump -uroot -p --host=localhost --all-databases--result-file=/tmp/mysqldump_result_file.txt 直接输出到指定文件中。该选项应该用在使用回车换行对 (\\r\\n) 换行的系统上(例如:DOS,Windows)。该选项确保只有一行被使用
--routines, -R mysqldump -uroot -p --host=localhost --all-databases --routines 导出存储过程以及自定义函数
--set-charset $ mysqldump -uroot -p --host=localhost --all-databases $ mysqldump -uroot -p --host=localhost --all-databases --skip-set-charset 添加 'SET NAMES default_character_set' 到输出文件。默认为打开状态,使用 --skip-set-charset 关闭选项
--single-transaction mysqldump -uroot -p --host=localhost --all-databases --single-transaction 该选项在导出数据之前提交一个 BEGIN SQL 语句,BEGIN不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于多版本存储引擎,仅 InnoDB。本选项和--lock-tables 选项是互斥的,因为 LOCK TABLES 会使任何挂起的事务隐含提交。要想导出大表的话,应结合使用 --quick 选项
--dump-date $ mysqldump -uroot -p --host=localhost --all-databases $ mysqldump -uroot -p --host=localhost --all-databases --skip-dump-date 将导出时间添加到输出文件中。默认为打开状态,使用 --skip-dump-date 关闭选项
--skip-opt mysqldump -uroot -p --host=localhost --all-databases --skip-opt 禁用 --opt 选项
--socket,-S mysqldump -uroot -p --host=localhost --all-databases --socket=/tmp/mysqld.sock 指定连接 mysqlsocket文件位置,默认路径/tmp/mysql.sock
--tab,-T mysqldump -uroot -p --host=localhost test test --tab="/home/mysql" 为每个表在给定路径创建 tab 分割的文本文件。注意:仅仅用于 mysqldumpmysqld服务器运行在相同机器上。注意使用 --tab 不能指定 --databases 参数
--tables mysqldump -uroot -p --host=localhost --databases test --tables test 覆盖 --databases (-B) 参数,指定需要导出的表名,在后面的版本会使用 table 取代tables
--triggers mysqldump -uroot -p --host=localhost --all-databases --triggers 导出触发器。该选项默认启用,用 --skip-triggers 禁用它
--tz-utc mysqldump -uroot -p --host=localhost --all-databases --tz-utc 在导出顶部设置时区 TIME_ZONE='+00:00',以保证在不同时区导出的TIMESTAMP 数据或者数据被移动其他时区时的正确性
--user, -u mysqldump -uroot -p 指定连接的用户名
--verbose, –v mysqldump -uroot -p --verbose 输出多种平台信息
--version, -V mysqldump -uroot -p --version 输出 mysqldump 版本信息并退出
--where, -w mysqldump -uroot -p --host=localhost --all-databases --where=” user=’root’” 只转储给定的 WHERE 条件选择的记录。请注意如果条件包含命令解释符专用空格或字符,一定要将条件引用起来
--xml, -X mysqldump -uroot -p --host=localhost --all-databases --xml 导出 XML 格式
--plugin_dir mysqldump -uroot -p --host=localhost --all-databases--plugin_dir=”/usr/local/lib/plugin” 客户端插件的目录,用于兼容不同的插件版本
--default_auth mysqldump -uroot -p --host=localhost --all-databases--default-auth=”/usr/local/lib/plugin/ 客户端插件默认使用权限

参考链接:
https://blog.csdn.net/qq_26975307/article/details/124367186
https://www.mobaijun.com/posts/2902111757.html
https://www.itshiye.com/29/7553.html

posted @ 2023-05-15 18:58  快乐小洋人  阅读(137)  评论(0)    收藏  举报