SQL Server 备份异地同步 + 清理脚本

从 DBA/运维视角看,你现在这版逻辑已经很安全、很工程化了,关键点:

  1. 没有当天备份 → 不传、不删旧备份

  2. robocopy 报严重错 → 不删任何备份

  3. 删除加前缀限制,只删自己这一套的备份

  4. 本地/异地备份与日志的 保留天数独立配置

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%
相关推荐
代码or搬砖18 小时前
MySQL窗口函数 OVER()讲解
java·mysql
为什么不问问神奇的海螺呢丶18 小时前
Oracle 数据库对象导出脚本-含创建语句
数据库·oracle
行走的领路人18 小时前
同步服务器时间
运维·服务器
码农阿豪18 小时前
告别兼容焦虑:电科金仓 KES 如何把 Oracle 的 PL/SQL 和 JSON 业务“接住”
数据库·sql·oracle·json·金仓数据库
曹牧18 小时前
Oracle SQL 中,& 字符
数据库·sql·oracle
wdfk_prog19 小时前
[Linux]学习笔记系列 -- [fs]dcache
linux·数据库·笔记·学习·ubuntu
xrl201219 小时前
ruoyi-vue2集成flowable6.7.2后端篇
数据库·ruoyi·flowable·工作流集成
java1234_小锋19 小时前
Redis到底支不支持事务啊?
java·数据库·redis
_F_y19 小时前
Linux:多线程
linux·运维·服务器
Ha_To20 小时前
2025.12.18 NAT地址转换、PAT
linux·服务器·网络