从 DBA/运维视角看,你现在这版逻辑已经很安全、很工程化了,关键点:
-
没有当天备份 → 不传、不删旧备份 ✅
-
robocopy 报严重错 → 不删任何备份 ✅
-
删除加前缀限制,只删自己这一套的备份 ✅
-
本地/异地备份与日志的 保留天数独立配置 ✅
bash
@echo off
setlocal
rem ================== ① 基本配置 ==================
rem 服务器本地备份目录
set "SOURCE_DIR=F:\ecoprobak"
rem 目标共享目录
set "TARGET_DIR=\异地NFS备份服务器共享文件路径"
rem 备份文件名前缀(ecopro0516_backup_YYYY_MM_DD_xxx.bak)
set "BACKUP_PREFIX=ecopro0516_backup_"
rem 备份文件保留天数(含今天,超过这个天数的都删)
set "RETENTION_DAYS=7"
rem 日志目录(放在本地备份目录下)
set "LOG_DIR=%SOURCE_DIR%\logs"
if not exist "%LOG_DIR%" md "%LOG_DIR%"
rem 日志保留天数
set "LOG_RETENTION_DAYS=14"
rem ================== ② 生成日期相关变量 ==================
rem 获取当前本地时间:YYYYMMDDhhmmss...
for /f "tokens=2 delims==" %%I in ('wmic os get localdatetime /value ^| find "="') do (
set "datetime=%%I"
)
rem datetime 示例:20251121091543.500000+480
rem 取前 8 位作为 YYYYMMDD,用于日志文件名
set "LOG_DATE=%datetime:~0,8%"
rem CURRENT_DATE 用于备份文件名里的 YYYY_MM_DD
set "CURRENT_DATE=%datetime:~0,4%_%datetime:~4,2%_%datetime:~6,2%"
rem 要复制的文件名(可匹配多文件)
set "FILE_NAME=%BACKUP_PREFIX%%CURRENT_DATE%*.bak"
rem 日志文件(按日期生成)
set "LOG_FILE=%LOG_DIR%\backup_%LOG_DATE%.log"
echo ================== 开始传输备份 ==================
echo 源目录: %SOURCE_DIR%
echo 目标目录: %TARGET_DIR%
echo 备份文件通配: %FILE_NAME%
echo 日志文件: %LOG_FILE%
echo.>>"%LOG_FILE%"
echo ================== NEW RUN ==================>>"%LOG_FILE%"
echo [%date% %time%] start backup>>"%LOG_FILE%"
rem ===== 先检查:今天的备份文件是否存在,不存在就不传、不清理备份 =====
if not exist "%SOURCE_DIR%\%FILE_NAME%" (
echo [警告] 未在本地目录找到当天备份文件:%SOURCE_DIR%\%FILE_NAME%
echo [警告] 跳过传输和备份清理,仅执行日志清理。请检查备份作业!
echo [%date% %time%] no today backup file found: %SOURCE_DIR%\%FILE_NAME%>>"%LOG_FILE%"
set "RC=9"
goto CLEAN_LOG_ONLY
)
rem ================== ③ 执行 robocopy 并记录日志 ==================
rem /R:3 重试 3 次,/W:5 每次间隔 5 秒
rem /LOG+ 把 robocopy 明细写入日志,/TEE 同时在屏幕输出
robocopy "%SOURCE_DIR%" "%TARGET_DIR%" "%FILE_NAME%" /R:3 /W:5 /LOG+:"%LOG_FILE%" /TEE
set "RC=%ERRORLEVEL%"
echo [%date% %time%] robocopy ERRORLEVEL=%RC%>>"%LOG_FILE%"
rem robocopy 返回码:
rem 0~7 视为成功或可接受
rem >=8 视为失败/严重错误
if %RC% GEQ 8 (
echo [警告] robocopy 失败或严重错误,跳过清理旧备份,请检查日志:%LOG_FILE%
echo [%date% %time%] robocopy failed, skip backup cleanup>>"%LOG_FILE%"
goto CLEAN_LOG_ONLY
)
rem ================== ④ 清理本地和异地超期备份 ==================
echo.
echo ================== 清理本地超期备份(>%RETENTION_DAYS% 天) ==================
echo [%date% %time%] clean local older than %RETENTION_DAYS% days>>"%LOG_FILE%"
forfiles /P "%SOURCE_DIR%" /M "%BACKUP_PREFIX%*.bak" /D -%RETENTION_DAYS% /C "cmd /c del /q @path"
echo.
echo ================== 清理异地超期备份(>%RETENTION_DAYS% 天) ==================
echo [%date% %time%] clean remote older than %RETENTION_DAYS% days>>"%LOG_FILE%"
forfiles /P "%TARGET_DIR%" /M "%BACKUP_PREFIX%*.bak" /D -%RETENTION_DAYS% /C "cmd /c del /q @path"
echo [%date% %time%] backup cleanup done>>"%LOG_FILE%"
:CLEAN_LOG_ONLY
rem ================== ⑤ 清理超期日志文件 ==================
echo.
echo ================== 清理日志文件(>%LOG_RETENTION_DAYS% 天) ==================
echo [%date% %time%] clean logs older than %LOG_RETENTION_DAYS% days>>"%LOG_FILE%"
forfiles /P "%LOG_DIR%" /M "backup_*.log" /D -%LOG_RETENTION_DAYS% /C "cmd /c del /q @path"
echo [%date% %time%] log cleanup done>>"%LOG_FILE%"
:END
echo.
echo 任务完成,robocopy 返回码:%RC%
echo [%date% %time%] job end, rc=%RC%>>"%LOG_FILE%"
endlocal & exit /b %RC%
