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%
相关推荐
O***Z6161 小时前
Redis——Windows安装
数据库·windows·redis
0***h9421 小时前
MySQL 启动失败 (code=exited, status=1FAILURE) 异常解决方案
数据库·mysql
极地星光1 小时前
C++链式调用设计:打造优雅流式API
服务器·网络·c++
闲人编程1 小时前
Django测试框架深度使用:Factory Boy与Fixture对比
数据库·python·django·sqlite·钩子·fixture·codecapsule
以明志、1 小时前
并行与并发
前端·数据库·c#
5***V9331 小时前
SQL 基础 BETWEEN 的常见用法
数据库·sql·mybatis
q***48412 小时前
Nginx中$http_host、$host、$proxy_host的区别
运维·nginx·http
橘子真甜~2 小时前
C/C++ Linux网络编程8 - epoll + ET Reactor TCP服务器
linux·服务器·网络