在我的 SQL Server 实例上,我使用 SQL Agent 分两步运行每日备份作业。
其中一个步骤使用 Robocopy 将本地备份文件移动到网络存储。
移动文件的命令如下所示:
robocopy M:\backups \\NAS\backups$\Database /MOV /MIR /XJ /NP /COPY:DT
作业步骤历史记录中命令的输出如下所示:
-------------------------------------------------------------------------------
ROBOCOPY :: Robust File Copy for Windows
-------------------------------------------------------------------------------
Started : Fri Jul 20 00:55:42 2012
Source : M:\backups\
Dest : \\NAS\backups$\Database
Files : *.*
Options : *.* /S /E /COPY:DT /MOV /PURGE /MIR /NP /XJ /R:1000000 /W:30
------------------------------------------------------------------------------
3 M:\backups\
*EXTRA File 15.5 m GeoDisplay_Full_2012-07-19-000004.bak
*EXTRA File 41.3 m GeoDisplay2_Full_2012-07-19-000004.bak
*EXTRA File 264.1 g Webstore_Full_2012-07-19-000004.bak
New File 15.5 m GeoDisplay_Full_2012-07-20-000002.bak
New File 41.4 m GeoStore_Full_2012-07-20-000002.bak
New File 302.1 g Webstore_Full_2012-07-20-000002.bak
2012/07/20 04:34:50 ERROR 32 (0x00000020) Deleting Source File M:\backups\Webstore_Full_2012-07-20-000002.bak The process cannot access the file because it is being used by another process.
------------------------------------------------------------------------------
Total Copied Skipped Mismatch FAILED Extras
Dirs : 1 0 1 0 0 0
Files : 3 3 0 0 0 3
Bytes : 302.187 g 302.187 g 0 0 0 264.181 g
Times : 3:38:57 3:38:45 0:00:00 0:00:11
Speed : 24720063 Bytes/sec.
Speed : 1414.493 MegaBytes/min.
Ended : Fri Jul 20 04:34:50 2012.
Process exit code 3.
文本输出清楚地显示ERROR 32。Robocopy 无法执行此/MOV
切换(复制后从源中删除),因为当 robocopy 尝试删除一个文件时,另一个进程拥有该文件的句柄。
Robocopy 返回退出代码 3(新文件复制到目标,额外文件从目标删除)。这是正确但不完整的,因为无法从错误代码中判断任何操作失败。
在确定命令 shell 操作是否成功时,SQL 代理仅考虑返回代码,而不考虑命令输出。我可以修改 Robocopy 命令以将输出保存到磁盘,并在额外的作业步骤中解析输出,但这需要额外的编程并且会向备份作业添加另一个依赖项。
有没有办法在不搜索 Robocopy 的文本输出字符串的情况下检测这种故障ERROR 32
?
无论是 RoboCopy 还是其他一些方法,我更喜欢记录所有输出,然后对日志进行后处理。我个人更喜欢 Perl 来完成这项任务,但可以使用任何您喜欢的语言。我也喜欢让测试检查脚本通过电子邮件将结果发送给我,显示它是否成功,或者在失败的情况下显示日志中的相关行。
在我看来,任何不包括报告结果的备份操作都是等待发生的灾难,仅仅是因为您不可能对未经检查的操作有信心。人类在检查日志方面做得非常糟糕,所以要付出额外的努力来编写脚本。没有它,您几乎可以保证某天某些关键操作会失败,而您对此一无所知,所冒的风险可能远不止数据。
退出代码描述“新文件复制到目标和额外文件从目标删除”在技术上不准确。你不应该只依赖描述。
退出代码 0x3 是位标志。友好消息应解释如下:
“成功复制了多个文件之一”
加
“检测到额外的文件或目录。 检查日志文件以获取更多信息。”
Robocopy 退出代码
https://blogs.technet.com/b/deploymentguys/archive/2008/06/16/robocopy-exit-codes.aspx
结果是约翰是正确的。如果您想进行可靠的备份操作,就没有办法绕过检查日志。此外,您可能希望有一个脚本在 Robocopy 操作之后运行,该脚本删除悬空文件的句柄,然后删除这些文件。