参考https://tecadmin.net/mysqldump-unknown-table-column_statistics-in-information_schema/

在 mariadb 中使用mysqldump备份时报错:

mysqldump: Unknown table 'column_statistics' in information_schema

这是因为在 mariadb 10.2.2 版本中引入了column_statistics表,而mysqldump是 mysql 的备份工具,不支持 mariadb 的新特性,无法识别column_statistics表。

解决方式是在备份时添加--column-statistics=0参数:

mysqldump --column-statistics=0 --opt -u root -p database_name > backup.sql

在 spring 中进行自动备份时,为解决上述问题,如果只在特定版本的 mariadb 中出现问题,则根据需要手动添加--column-statistics=0参数;如果不确定 mariadb 版本,或者要兼容多个版本,则可以在备份前先检查 mariadb 版本,然后根据版本添加--column-statistics=0参数。

检查 mariadb 版本:

@Select("select version()")
String getDatabaseVersion();

获取到的版本号格式为10.6.11-MariaDB

自动备份代码: ```java

@Service public class LogScheduledTask {

@Autowired
private LogService logService;

@Value("${spring.datasource.url}")
private String databaseUrl;

@Value("${spring.datasource.username}")
private String databaseUsername;

@Value("${spring.datasource.password}")
private String databasePassword;

@Scheduled(cron = "0 0 1 * * ?")
public void backup() {
    String mariadbVersion = logService.getDatabaseVersion();
    String cmd1 = "cmd /c mysqldump ";
    String cmd2 = "cmd /c mysqldump --column-statistics=0 ";
    String backupPath = "backup/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + ".sql";
    String cmdParams = "--opt -u " + databaseUsername + " --password=" + databasePassword + " -h" + databaseHost + " test > " + backupPath;
    try {
        String cmd;
        if (compareVersion(mariadbVersion.split("-")[0], "10.2.2") >= 0) {
            cmd = cmd2 + cmdParams;
        } else {
            cmd = cmd1 + cmdParams;
        }
        Process process = Runtime.getRuntime().exec(cmd);
        int exitCode = process.waitFor();
        if (exitCode == 0) {
            logService.saveLog("备份成功");
        } else {
            logService.saveLog("备份失败");
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private int compareVersion(String version1, String version2) {
    if (version1 == null || version2 == null) {
        return 0;
    }
    String[] versionArray1 = version1.split("\\.");//注意此处为正则匹配,不能用".";
    String[] versionArray2 = version2.split("\\.");
    int idx = 0;
    int minLength = Math.min(versionArray1.length, versionArray2.length);//取最小长度值
    int diff = 0;
    while (idx < minLength && (diff = Integer.parseInt(versionArray1[idx]) - Integer.parseInt(versionArray2[idx])) == 0) {
        ++idx;
    }
    //如果已经分出大小,则直接返回,如果未分出大小,则再比较位数,有子版本的为大;
    diff = (diff != 0) ? diff : versionArray1.length - versionArray2.length;
    return diff;
} }