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%
相关推荐
SPC的存折14 小时前
MySQL 8.0 分库分表
linux·运维·服务器·数据库·mysql
蓦然乍醒14 小时前
使用 DBeaver 还原 PostgreSQL 备份文件 (.bak) 技术文档
数据库·postgresql
XDHCOM14 小时前
Redis节点故障自动恢复机制详解,如何快速抢救故障节点,确保数据不丢失?
java·数据库·redis
风吹迎面入袖凉14 小时前
【Redis】Redisson分布式锁原理
java·服务器·开发语言
QCzblack14 小时前
BugKu BUUCTF ——Reverse
java·前端·数据库
cyber_两只龙宝14 小时前
【Oracle】Oracle之DQL中WHERE限制条件查询
linux·运维·数据库·云原生·oracle
luis的妙妙屋14 小时前
主流数据库数据类型对比分析
数据库
斌味代码14 小时前
Shell 性能监控:指标采集、告警规则与可视化大盘设计
运维
XDHCOM14 小时前
ORA-00054资源忙故障修复,远程处理Oracle报错解决方案,数据库锁超时NOWAIT指定问题排查
数据库·oracle
22信通小白14 小时前
USRP初学者使用手册(基础配置及bug记录)——Linux+Clion(单台X310收发)
linux·运维·c++·5g·bug·信息与通信