SQL Server批量还原事务日志至Standby模式脚本故障排查
故障排查结论
你当前脚本不执行还原操作的核心原因有两个:
- 仅通过
PRINT输出拼接好的还原命令,没有添加执行动态SQL的逻辑,所有命令只打印到消息栏不会实际运行 - 拼接的RESTORE LOG语句存在语法缺失,末尾未闭合
STANDBY参数的单引号,就算加了执行逻辑也会报语法错误
除此之外脚本还存在3个会导致还原失败的隐患:
- 未过滤
xp_cmdshell返回的空值、无效行,游标可能读取到非TRN备份的无效内容 - 未对事务日志备份按生成顺序排序,乱序应用日志会直接触发LSN不匹配错误
- 未校验数据库当前状态,若数据库不在Standby/还原状态下,执行还原会直接报错
修复后可直接运行的脚本
USE Master; GO SET NOCOUNT ON -- 1 - 变量声明 DECLARE @dbName sysname DECLARE @backupPath NVARCHAR(500) DECLARE @cmd NVARCHAR(MAX) DECLARE @fileList TABLE (backupFile NVARCHAR(255)) DECLARE @backupFile NVARCHAR(500) -- 2 - 初始化参数 SET @dbName = 'Telcor' SET @backupPath = 'D:\TelcorLogDump\' -- 校验数据库是否处于可用的Standby还原状态 IF NOT EXISTS ( SELECT 1 FROM sys.databases WHERE name = @dbName AND state = 1 -- 1=RESTORING状态,Standby模式下数据库处于该状态 ) BEGIN RAISERROR('数据库%s不在Standby还原状态,无法应用事务日志',16,1,@dbName) RETURN END -- 3 - 获取目录下所有备份文件 SET @cmd = 'DIR /b "' + @backupPath + '"' INSERT INTO @fileList(backupFile) EXEC master.sys.xp_cmdshell @cmd -- 声明游标:过滤无效行、筛选目标库TRN备份、按文件名排序(需保证文件名带时间戳可对应备份先后顺序) DECLARE backupFiles CURSOR FOR SELECT backupFile FROM @fileList WHERE backupFile IS NOT NULL AND backupFile LIKE '%.TRN' AND backupFile LIKE @dbName + '%' ORDER BY backupFile ASC OPEN backupFiles -- 循环遍历所有日志备份执行还原 FETCH NEXT FROM backupFiles INTO @backupFile WHILE @@FETCH_STATUS = 0 BEGIN -- 拼接还原命令,补全STANDBY参数的闭合单引号 SET @cmd = 'RESTORE LOG [' + @dbName + '] FROM DISK = ''' + @backupPath + @backupFile + ''' WITH STANDBY = N''D:\TelcorLogDump\ROLLBACK_UNDO_Telcor.BAK''' PRINT '正在执行还原命令: ' + @cmd -- 执行动态SQL(原脚本缺失这一步,是不会执行还原的核心原因) EXEC (@cmd) -- 若单步还原报错则终止循环 IF @@ERROR <>0 BEGIN RAISERROR('还原日志文件%s时出错,终止执行',16,1,@backupFile) BREAK END FETCH NEXT FROM backupFiles INTO @backupFile END CLOSE backupFiles DEALLOCATE backupFiles
使用注意事项
- 需提前开启
xp_cmdshell配置权限,且SQL Server服务启动账号对D:\TelcorLogDump\目录拥有读写权限 - 需保证所有待还原的TRN备份文件名包含可排序的时间戳,否则按文件名排序可能和实际备份LSN顺序不一致,导致还原失败;如果文件名无时间戳,需要先通过
RESTORE HEADERONLY读取每个备份的FirstLSN字段排序后再应用 - 应用日志过程中不能对数据库执行RESTORE WITH RECOVERY操作,否则日志链会断裂,后续无法继续还原日志
- STANDBY参数指定的ROLLBACK_UNDO_Telcor.BAK文件不要手动删除或移动路径,否则后续日志还原会失败
内容的提问来源于stack exchange,提问作者Asha Richardson
相关产品推荐
相关产品推荐

