Windows使用mysqldump定时执行任务备份的sql文件0kb

本文介绍了如何处理mysqldump备份时生成的sql文件大小为0KB的故障。主要检查环境变量配置,确保mysqldump路径无空格,并提供了解决该问题的具体操作步骤,包括复制mysqldump到无空格路径并更新环境变量。

Windows使用mysqldump定时执行任务备份的sql文件0kb

1.首先确定mysqldump的环境变量已经配置了

比如mysqldump所在路径为D:\mysql\mysql-5.7.30-winx64\bin,那我们应该在环境变量的PATH中配置mysqldump的环境变量

在这里插入图片描述

不会配置的当我没说

2.mysqldump所在的文件夹路径中有空格,所有导致备份导出的sql文件0kb

这时候我们只要将mysqldump.exe复制一份出来放在一个路径不带空格的文件夹下即可

比如:

之前的脚本写法是路径带空格的

在这里插入图片描述

我现在把mysqldump.exe复制到别的文件夹下,这个文件夹路径不带空格

现在的写法是

在这里插入图片描述

并且我们环境变量已经配置了,所以可以直接用

如果还不行的话,那就只能是其他的错误了,耗子尾汁

在这里插入图片描述

package com.Ls.erp.util; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.*; import java.nio.file.Files; import java.nio.file.attribute.BasicFileAttributes; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @Component public class DatabaseBackupScheduler { // 配置参数(根据实际情况修改) private static final String DB_HOST = "localhost"; private static final String DB_PORT = "3306"; private static final String DB_USER = "root"; private static final String DB_PASSWORD = "000000"; private static final String DATABASE_NAME = "erp"; private static final String BACKUP_DIR = "D://2023-02-23ERP测试//2025-08-01//数据库备份查询"; // 替换为实际备份目录 private static final int RETENTION_DAYS = 15; // 保留最近15天的备份 private static final String MYSQLDUMP_PATH = getMysqldumpPath(); @PostConstruct public void init() { startScheduledBackup(); } private static String getMysqldumpPath() { String os = System.getProperty("os.name").toLowerCase(); if (os.contains("win")) { return "C:\\Program Files\\MySQL\\MySQL Server 5.7\\bin\\mysqldump.exe"; } else { return "/usr/bin/mysqldump"; } } private static void startScheduledBackup() { ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); // 计算首次执行时间 Calendar now = Calendar.getInstance(); Calendar nextBackupTime = calculateNextBackupTime(now); // 计算初始延迟(毫秒) long initialDelay = nextBackupTime.getTimeInMillis() - now.getTimeInMillis(); // 每天执行一次(24小时) long period = 24 * 60 * 60 * 1000; scheduler.scheduleAtFixedRate( DatabaseBackupScheduler::performBackup, initialDelay, period, TimeUnit.MILLISECONDS ); System.out.println("数据库备份任务已启动。首次备份时间: " + nextBackupTime.getTime()); System.out.println("备份目录: " + BACKUP_DIR); System.out.println("备份保留天数: " + RETENTION_DAYS + "天"); } private static Calendar calculateNextBackupTime(Calendar currentTime) { Calendar nextTime = (Calendar) currentTime.clone(); // 设置备份时间点(12:00 和 17:30) List<Calendar> backupTimes = new ArrayList<>(); Calendar noon = Calendar.getInstance(); noon.set(Calendar.HOUR_OF_DAY, 12); noon.set(Calendar.MINUTE, 0); noon.set(Calendar.SECOND, 0); Calendar evening = Calendar.getInstance(); evening.set(Calendar.HOUR_OF_DAY, 14); evening.set(Calendar.MINUTE, 25); evening.set(Calendar.SECOND, 0); backupTimes.add(noon); backupTimes.add(evening); // 找到下一个最近的备份时间 for (Calendar time : backupTimes) { if (time.after(currentTime)) { return time; } } // 如果今天所有时间点都已过,返回明天的第一个时间点 Calendar firstTime = backupTimes.get(0); firstTime.add(Calendar.DAY_OF_MONTH, 1); return firstTime; } private static void performBackup() { try { // 创建备份目录(如果不存在) File backupDir = new File(BACKUP_DIR); if (!backupDir.exists() && !backupDir.mkdirs()) { System.err.println("无法创建备份目录: " + BACKUP_DIR); return; } // 生成带时间戳的文件名 String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String fileName = String.format("%s_%s.sql", DATABASE_NAME, timeStamp); String backupPath = BACKUP_DIR + File.separator + fileName; // 构建备份命令 List<String> command = new ArrayList<>(); command.add(MYSQLDUMP_PATH); command.add("--host=" + DB_HOST); command.add("--port=" + DB_PORT); command.add("--user=" + DB_USER); command.add("--password=" + DB_PASSWORD); command.add("--databases"); command.add(DATABASE_NAME); command.add("--result-file=" + backupPath); command.add("--skip-lock-tables"); command.add("--single-transaction"); command.add("--routines"); // 备份存储过程和函数 command.add("--events"); // 备份事件 command.add("--triggers"); // 备份触发器 // 添加以下关键参数 command.add("--default-character-set=utf8mb4"); command.add("--hex-blob"); // 处理二进制字段 command.add("--skip-comments"); // 避免注释导致问题 command.add("--no-tablespaces"); // 避免权限问题 command.add("--verbose"); // 显示更多信息 // 执行备份命令 ProcessBuilder processBuilder = new ProcessBuilder(command); // 关键修复:使用标准输出重定向 File backupFile = new File(backupPath); processBuilder.redirectOutput(backupFile); // 正确重定向输出到文件 processBuilder.redirectErrorStream(true); // 合并错误流到输出流 System.out.println("[" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "] 开始备份数据库: " + DATABASE_NAME); Process process = processBuilder.start(); // 读取命令输出 try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { String line; while ((line = reader.readLine()) != null) { System.out.println("[MYSQLDUMP] " + line); } } int exitCode = process.waitFor(); if (exitCode == 0) { long fileSizeKB = backupFile.length() / 1024; System.out.println("✅ 数据库备份成功: " + backupPath); System.out.println("📁 备份文件大小: " + fileSizeKB + " KB"); // 验证备份文件 if (isBackupValid(backupFile)) { System.out.println("🔍 备份文件验证通过"); } else { System.err.println("⚠️ 备份文件验证失败,可能存在数据丢失"); } // 清理旧备份 cleanOldBackups(); } else { System.err.println("❌ 数据库备份失败,退出码: " + exitCode); // 记录详细错误信息 try (BufferedReader errorReader = new BufferedReader( new InputStreamReader(process.getErrorStream()))) { String errorLine; while ((errorLine = errorReader.readLine()) != null) { System.err.println("[MYSQLDUMP ERROR] " + errorLine); } } catch (IOException e) { System.err.println("无法读取错误流: " + e.getMessage()); } } } catch (IOException | InterruptedException e) { System.err.println("⚠️ 备份过程中发生错误: " + e.getMessage()); e.printStackTrace(); } } // 新增方法:验证备份文件完整性 private static boolean isBackupValid(File backupFile) { try (BufferedReader reader = new BufferedReader(new FileReader(backupFile))) { boolean hasCreateTable = false; boolean hasInsert = false; boolean hasEndMarker = false; String line; int lineCount = 0; while ((line = reader.readLine()) != null) { lineCount++; // 检查关键结构 if (line.startsWith("CREATE TABLE")) hasCreateTable = true; if (line.startsWith("INSERT INTO")) hasInsert = true; if (line.contains("Dump completed")) hasEndMarker = true; // 检查错误信息 if (line.contains("ERROR") || line.contains("failed")) { System.err.println("备份文件中发现错误: " + line); return false; } } // 基本完整性检查 if (lineCount < 100) { System.err.println("备份文件行数不足: " + lineCount); return false; } if (!hasCreateTable) { System.err.println("缺少CREATE TABLE语句"); return false; } if (!hasInsert) { System.err.println("缺少INSERT INTO语句"); return false; } return hasEndMarker; } catch (IOException e) { System.err.println("验证备份文件时出错: " + e.getMessage()); return false; } } private static void cleanOldBackups() { File backupDir = new File(BACKUP_DIR); if (!backupDir.exists() || !backupDir.isDirectory()) { return; } // 计算截止时间(当前时间减去保留天数) long cutoff = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(RETENTION_DAYS); // 获取所有备份文件 File[] backupFiles = backupDir.listFiles((dir, name) -> name.startsWith(DATABASE_NAME + "_") && name.endsWith(".sql") ); if (backupFiles == null || backupFiles.length == 0) { return; } int deletedCount = 0; for (File backup : backupFiles) { try { // 获取文件的创建时间 BasicFileAttributes attrs = Files.readAttributes( backup.toPath(), BasicFileAttributes.class ); // 如果文件创建时间早于截止时间,则删除 if (attrs.creationTime().toMillis() < cutoff) { if (backup.delete()) { System.out.println("♻️ 已清理旧备份: " + backup.getName()); deletedCount++; } else { System.err.println("⚠️ 无法删除旧备份: " + backup.getName()); } } } catch (IOException e) { System.err.println("⚠️ 检查备份文件时出错: " + backup.getName() + " - " + e.getMessage()); } } System.out.println("🧹 清理完成: 共删除 " + deletedCount + " 个旧备份"); } } 我可以在Java里面去做这个事情吗,我需要的mysql、里面的erp库进行数据与结构的保存,我使用这个好像可以保存erp里面的时间但是存在问题,保存的erp.sql,文件大小是16000KB我手动去mysql里面对erp进行保存,sql文件大小是28430KB还有我去运行erp里面的数据,全部是报错的,我代码存在什么问题吗
08-02
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值