Shell脚本中SQLCMD执行RESTORE后无法及时退出的问题
SQLCMD执行SQL Server数据库恢复后长时间挂起无法退出
问题描述
- 编写Shell脚本实现自动下载并恢复SQL Server数据库,脚本可正常完成
.bak文件下载,但执行数据库恢复后,SQLCMD进程会异常挂起 - 恢复操作本身5-30秒即可完成并报告成功,但之后脚本会挂起约10分钟,SQLCMD进程才会退出,脚本才能继续执行
- 脚本逻辑:先检查SFTP服务器上是否存在比上次下载更新的
.bak文件,若有则下载,随后执行由Azure Data Studio恢复功能生成的数据库恢复脚本 - 当前在M2 Mac终端手动运行脚本,后续计划通过cron实现自动化,数据库部署在Docker容器中
更新于2023年1月24日:SQLCMD进程最终会退出,但设置SQLCMD的
-t超时参数无法缩短恢复完成后的等待时长
环境信息
- SQL Server 2022 (RTM-CU11) (KB5032679) - 16.0.4105.2 (X64),运行于Ubuntu 22.04.3 LTS
- Mac OS Sonoma 14.2.1 (23C71)
- OrbStack 1.3.0 (16556)
恢复脚本代码
#!/usr/bin/zsh ### 下载代码省略 tail_log_date=$(date +"%Y-%m-%d_%H-%M-%S") new_latest_full=$(ls -r -1 /Path/to/container/var/opt/mssql/sldbBackup/full | head -1) new_latest_diff=$(ls -r -1 /Path/to/container/var/opt/mssql/sldbBackup/diff | head -1) docker exec container_name opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P <password> -d my_database -Q "USE [master] ALTER DATABASE [my_database] SET SINGLE_USER WITH ROLLBACK IMMEDIATE BACKUP LOG [my_database] TO DISK = N'/var/opt/mssql/data/my_database_LogBackup_${tail_log_date}.bak' WITH NOFORMAT, NOINIT, NAME = N'my_database_LogBackup_${tail_log_date}', NOSKIP, NOREWIND, NOUNLOAD, NORECOVERY , STATS = 5 RESTORE DATABASE [my_database] FROM DISK = N'/var/opt/mssql/sldbBackup/full/${new_latest_full}' WITH FILE = 1, MOVE N'mscrm' TO N'/var/opt/mssql/data/my_database.mdf', MOVE N'mscrm_log' TO N'/var/opt/mssql/data/my_database_log.ldf', NORECOVERY, NOUNLOAD, REPLACE, STATS = 5 RESTORE DATABASE [my_database] FROM DISK = N'/var/opt/mssql/sldbBackup/diff/${new_latest_diff}' WITH FILE = 1, NOUNLOAD, STATS = 5 ALTER DATABASE [my_database] SET MULTI_USER;"
已尝试的解决操作
- 添加SQLCMD的
-b参数(错误时立即退出),无改善 - 将恢复脚本替换为简单的SELECT查询时,SQLCMD可正常退出,问题仅出现在数据库恢复操作场景
- 恢复操作是否放在IF条件中执行,不影响最终挂起的结果
内容的提问来源于stack exchange,提问作者TRezendes
相关产品推荐
相关产品推荐

