springboot: copia de seguridad automática de los datos de mysql todos los días

1. Descripción

Usar tecnología: mysqldump mysql viene con herramientas

Operación simple de la copia de seguridad de mysqldump:

  • mysqldump -h [ip] -P [número de puerto] -u [nombre de usuario] -p [contraseña] nombre de la base de datos nombre de la tabla> nombre del archivo exportado.sql

  • mysqldump -h [ip] -P [número de puerto] -u [nombre de usuario] -p [contraseña] nombre de la base de datos nombre de la tabla 1 nombre de la tabla 2 nombre de la tabla 3 | gzip> nombre del archivo exportado.sql.gz

gzip se comprime y exporta directamente, y es necesario instalar el comando gzip.
Referencia: https://blog.csdn.net/yuxisanno139/article/details/83016520

Dos, usa

  • win abre cmd para ejecutar comandos, linux usa directamente
  • La ejecución de Win cmd requiere que la PC actual instale mysql
  • Para ejecutar el servidor, debe instalar mysql o mysqldump por separado. Comandos de instalación separados: yum -y install holland-mysqldump.noarch
  • La diferencia entre win y cmd está en el último directorio de guardado de archivos, preste atención para reemplazar
  • La versión de mysql8 + requiere el parámetro --column-statistics = 0, la versión de mysql8- elimine este parámetro
  • Parece sql_mode=...incorrecto ver un método de error de manipulación

No comprima la copia de seguridad

mysqldump --column-statistics=0 -u账号 -p密码 -h域名或ip -P3306 --databases 数据库名  > F:/sql/spring-boot-plus2.sql

La copia de seguridad comprimida (agregar | gzip)
necesita instalar el comando gzip, referencia: referencia: https://blog.csdn.net/yuxisanno139/article/details/83016520

mysqldump --column-statistics=0  -u账号 -p密码 -h域名或ip -P3306 --databases 数据库名  | gzip > F:/sql/spring-boot-plus2.gz

Tres, descripción del error

Error 1

Mensaje de error

mysqldump: [ERROR] unknown variable 'sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'.

Solución:
abra el directorio mysql para encontrar: el archivo my.ini, el comentario sql_mode=....de los datos de la línea

Error 2

Mensaje de error:

 Couldn't execute 'SELECT COLUMN_NAME,                       JSON_EXTRACT(HISTOGRAM, '$. ..............

Acercarse:

Agregar: --column-statistics = 0

Tres, uso integrado de springboot

Esta copia de seguridad utiliza una secuencia. Obtener los datos de la copia de seguridad mientras se escribe en el archivo es ligeramente diferente a utilizar directamente el comando.

Esta vez no escribí el archivo sql para comprimir y eliminar automáticamente los datos hace n días, puede manejarlo usted mismo

Nota: este código no puede usar compresión de comandos, solo compresión de código

package com.ws.ldy.task.sys;

import com.ws.ldy.common.utils.LocalDateTimeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.*;


/**
 * MYSQL 数据自动备份
 * <P>
 *    请参考文章: https://blog.csdn.net/qq_41463655/article/details/112628365
 * </P>
 * @author wangsong
 * @date 2021/1/14 0014 19:12
 * @return
 * @version 1.0.0
 */
@Component
@Configuration
@EnableScheduling
@Slf4j
public class MysqlDataBackup {
    
    


    /**
     * 备份 sql 存放目录(相对路径, 注意可能需要在 MvcConfig 配置访问权限)
     */
    String filePath = "File/sql/";

    /**
     * 数据库版本是否为 8.0 + (false=否  true=是), mysql8+ 需要参数  --column-statistics=0  , mysql8- 不需要
     */
    Boolean isDbVersion8 = false;

    /**
     * 备份命令
     * USERNAME   账号
     * PASSWORD   密码
     * SERVERPATH 服务器IP/域名
     * DBNAME     数据库名称
     * FILEPATH   备份文件存放地址+名称
     * 说明
     * cmdCompression : 需压缩 (本地或服务器需安装 mysqldump 命令(安装mysql自带患独立安装) +  gzip 命令(独立安装))
     * cmd :            不压缩 (本地或服务器需安装 mysqldump 命令(安装mysql自带患独立安装)
     * --column-statistics=0     mysql8 添加该参数, 非mysql8 不添加, 否则将出错
     */
    String cmdMysql8 = "mysqldump --column-statistics=0  -u{USERNAME} -p{PASSWORD} -h{SERVERPATH} -P3306 --databases {DBNAME}"; //  > {FILEPATH}.sql
    String cmd = "mysqldump  -u{USERNAME} -p{PASSWORD} -h{SERVERPATH} -P3306 --databases {DBNAME}";      //  > {FILEPATH}.sql


    @Value("${spring.datasource.dynamic.datasource.db1.url}")
    private String dbUrl;

    @Value("${spring.datasource.dynamic.datasource.db1.username}")
    private String dbUserName;

    @Value("${spring.datasource.dynamic.datasource.db1.password}")
    private String dbPassWord;


    /**
     * 每天凌晨4点 【  0 0 4 1/1 * ? 】
     * 测试 20 秒一次【  0/20 * * * * ? 】
     */
    @Scheduled(cron = "0 0 4 1/1 * ?")
    private void configureTasks() {
    
    
        log.info("【备份数据库】--START");
        String dbUrl2 = dbUrl.replace("jdbc:mysql://", "");

        // 获取数据库名称
        String dbName = dbUrl2.substring(dbUrl2.lastIndexOf("/") + 1, dbUrl2.indexOf("?"));
        // 获取数据库地址
        String serverPath = dbUrl2.substring(0, dbUrl2.lastIndexOf("/"));
        // 数据库账号
        String username = dbUserName;
        // 数据库密码
        String password = dbPassWord;

        // 备份文件目录+名称  备份文件存放目录+名称(名称 = 数据库名+时间字符串.sql)
        String timeStr = LocalDateTimeUtil.convertLDTToStr(LocalDateTimeUtil.now())
                .replaceAll("-", "_")
                .replaceAll(" ", "_")
                .replaceAll(":", "");
        timeStr = timeStr.substring(0, 15);
        String pathFileName = filePath + dbName + "_" + timeStr + ".sql";
        String newCmd = "";
        if (isDbVersion8) {
    
    
            newCmd = cmdMysql8;
        } else {
    
    
            newCmd = cmd;
        }
        // 执行命令
        newCmd =  newCmd.replace("{USERNAME}", username)
                .replace("{PASSWORD}", password)
                .replace("{SERVERPATH}", serverPath)
                .replace("{DBNAME}", dbName)
                .replace("{FILEPATH}", pathFileName);
        System.out.println(newCmd);
        PrintWriter printWriter = null;
        BufferedReader bufferedReader = null;
        try {
    
    
            // 创建存放sql的文件
            existsFile(new File(pathFileName));
            printWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(pathFileName), "utf8"));
            Process process = null;
            String property = System.getProperty("os.name");
            System.out.println(property);
            if (property.indexOf("Linux") != -1) {
    
    
                // linux
                process = Runtime.getRuntime().exec(new String[]{
    
    "bash", "-c", newCmd});
            } else {
    
    
                // 本地win
                process = Runtime.getRuntime().exec(newCmd);
            }
            InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream(), "utf8");
            bufferedReader = new BufferedReader(inputStreamReader);
            String line;
            while ((line = bufferedReader.readLine()) != null) {
    
    
                printWriter.println(line);
            }
            // 此次会执行过长时间,直到备份完成
            printWriter.flush();
            printWriter.close();
            //0 表示线程正常终止。
            if (process.waitFor() == 0) {
    
    
                // 线程正常执行
                log.info("【备份数据库】SUCCESS,SQL文件:{}", pathFileName);
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
            log.info("【备份数据库】FAILURE");
        } finally {
    
    
            try {
    
    
                if (bufferedReader != null) {
    
    
                    bufferedReader.close();
                }
                if (printWriter != null) {
    
    
                    printWriter.close();
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        log.info("【备份数据库】--END");
    }


    /**
     * 判断文件是否存在,不存在创建
     */
    private static void existsFile(File file) {
    
    
        // 判断文件路径是否存在,不存在新建
        if (!file.getParentFile().exists()) {
    
    
            file.getParentFile().mkdirs();
        }
        if (!file.exists()) {
    
    
            try {
    
    
                file.createNewFile();
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
    }
}

Visualización del catálogo de respaldo

win bajo el proyecto
Inserte la descripción de la imagen aquí
linux estará bajo la ruta raíz de implementación del proyecto
Inserte la descripción de la imagen aquí

  • Proyecto personal de código abierto (sistema de gestión de fondo universal) -> https://gitee.com/wslxm/spring-boot-plus2 , puede consultarlo si lo desea

  • Este es el final de este artículo. Si lo encuentra útil, por favor, haga clic en Me gusta o preste atención. Continuaremos actualizando más contenido de vez en cuando ... ¡Gracias por mirar!

Supongo que te gusta

Origin blog.csdn.net/qq_41463655/article/details/112628365
Recomendado
Clasificación