news 2026/4/23 13:45:18

Linux 环境下 SQL Server 自动收缩日志作业创建脚本(Shell 版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 环境下 SQL Server 自动收缩日志作业创建脚本(Shell 版)

随着SQL Server在Linux平台的普及,很多运维人员需要在Linux服务器上实现数据库日志的自动收缩。本文将原SQL脚本改造为适配Linux环境的Shell脚本,兼容SQL Server 2017及以上Linux版本(2017/2019/2022),保留全版本适配、安全合规、易维护的核心特性,同时贴合Linux系统的操作习惯。

一、完整Shell脚本

#!/bin/bash# =========================================================================# 脚本名称:sqlserver_shrink_log_job.sh# 适用环境:Linux + SQL Server 2017/2019/2022(x64)# 前置条件:# 1. Linux服务器已安装SQL Server,且启动sqlserver服务# 2. 已安装sqlcmd工具(/opt/mssql-tools/bin/sqlcmd)# 3. master库已创建dbo.ShrinkUser_DATABASESLogFile存储过程# 4. 执行脚本的Linux用户具备执行sqlcmd的权限# 核心功能:在Linux的SQL Server中创建自动收缩日志的定时作业# 作者:运维研发组# 日期:2025-12-16# =========================================================================set-euo pipefail# Shell严格模式:未定义变量报错、管道失败则脚本退出# ======================== 自定义配置参数(根据实际需求修改) ========================exportSQL_SERVER="localhost"# SQL Server实例地址(本地填localhost,远程填IP/主机名)exportSQL_USER="sa"# SQL登录账户(建议替换为低权限运维账户)# 建议通过环境变量传入密码,避免硬编码(执行前执行:export SQL_PWD="你的密码")# export SQL_PWD="YourStrongPassword" # 注释:生产环境请勿直接写入脚本!exportJOB_NAME="ShrinkFile_DB_Logfile"# 作业名称exportJOB_CATEGORY="Database Maintenance"# 作业分类exportSCHEDULE_NAME="Shrink_DB_Logfile_Schedule"# 调度名称exportDAILY_EXEC_TIME="050000"# 每日执行时间(HHMMSS,050000=凌晨5点)exportDELETE_EXIST_JOB="1"# 是否删除已存在的同名作业(1=删除,0=不删除)exportNOTIFY_LEVEL="2"# 作业失败时记录事件日志(0=不记录,2=失败记录)# ======================== 依赖检查 ========================# 检查sqlcmd是否安装if!command-v /opt/mssql-tools/bin/sqlcmd&>/dev/null;thenecho"【错误】未找到sqlcmd工具,请先安装:sudo apt-get install mssql-tools unixodbc-dev(Debian/Ubuntu)或 sudo yum install mssql-tools unixODBC-devel(RHEL/CentOS)"exit1fi# 检查密码是否传入if[-z"${SQL_PWD:-}"];thenecho"【错误】未设置SQL_PWD环境变量,请执行:export SQL_PWD='你的SQL账户密码' 后再运行脚本"exit1fi# 检查SQL Server服务是否运行(可选)if!systemctl is-active --quiet mssql-server;thenecho"【警告】SQL Server服务未运行,建议先启动:sudo systemctl start mssql-server"read-p"是否继续执行脚本?(y/n) "-n1-rechoif[[!$REPLY=~ ^[Yy]$]];thenexit1fifi# ======================== 构建TSQL脚本内容 ========================TSQL_SCRIPT=$(cat<<EOF SET NOCOUNT ON;SET XACT_ABORT ON;-- 检查依赖的收缩存储过程是否存在 IF NOT EXISTS(SELECT1FROM master.sys.objects WHERE name=N'ShrinkUser_DATABASESLogFile'ANDtype=N'P'AND schema_id=SCHEMA_ID(N'dbo'))BEGIN RAISERROR(N'前置条件不满足:master库中未找到dbo.ShrinkUser_DATABASESLogFile存储过程!',16,1);RETURN;END;-- 检查并处理已存在的同名作业 IF EXISTS(SELECT1FROM msdb.dbo.sysjobs WHERE name=N'$JOB_NAME')BEGIN IF$DELETE_EXIST_JOB=1BEGIN EXEC msdb.dbo.sp_delete_job @job_name=N'$JOB_NAME', @delete_unused_schedules=1;PRINT N'已删除同名作业:$JOB_NAME';END ELSE BEGIN RAISERROR(N'作业【%s】已存在,若需重新创建请将DELETE_EXIST_JOB设为1',16,1,N'$JOB_NAME');RETURN;END END BEGIN TRY BEGIN TRANSACTION;-- 创建作业分类(若不存在) IF NOT EXISTS(SELECT1FROM msdb.dbo.syscategories WHERE name=N'$JOB_CATEGORY'AND category_class=1)BEGIN DECLARE @ReturnCode INT=0;EXEC @ReturnCode=msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'$JOB_CATEGORY';IF @ReturnCode<>0BEGIN RAISERROR(N'创建作业分类【%s】失败,返回码:%d',16,1,N'$JOB_CATEGORY',@ReturnCode);END PRINT N'已创建作业分类:$JOB_CATEGORY';END -- 创建核心作业 DECLARE @JobId BINARY(16), @ReturnCode INT=0;EXEC @ReturnCode=msdb.dbo.sp_add_job @job_name=N'$JOB_NAME', @enabled=1, @notify_level_eventlog=$NOTIFY_LEVEL, @notify_level_email=0, @notify_level_netsend=0, @notify_level_page=0, @delete_level=0, @description=N'Linux环境自动收缩用户数据库日志文件(适配SQL Server Linux版),依赖master.dbo.ShrinkUser_DATABASESLogFile存储过程', @category_name=N'$JOB_CATEGORY', @owner_login_name=N'$SQL_USER', @job_id=@JobId OUTPUT;IF @ReturnCode<>0BEGIN RAISERROR(N'创建作业【%s】失败,返回码:%d',16,1,N'$JOB_NAME',@ReturnCode);END PRINT N'已创建作业主体:$JOB_NAME';-- 添加作业执行步骤 EXEC @ReturnCode=msdb.dbo.sp_add_jobstep @job_id=@JobId, @step_name=N'Execute_Shrink_Log_Procedure', @step_id=1, @cmdexec_success_code=0, @on_success_action=1, @on_success_step_id=0, @on_fail_action=2, @on_fail_step_id=0, @retry_attempts=0, @retry_interval=0, @os_run_priority=0, @subsystem=N'TSQL', @command=N' BEGIN TRY PRINT N''开始执行日志收缩存储过程:''+ CONVERT(NVARCHAR(30), GETDATE(),120);EXEC master.dbo.ShrinkUser_DATABASESLogFile;PRINT N''日志收缩存储过程执行完成:''+ CONVERT(NVARCHAR(30), GETDATE(),120);END TRY BEGIN CATCH DECLARE @ErrMsg NVARCHAR(4000)=ERROR_MESSAGE();RAISERROR(N''收缩日志失败:%s'',16,1,@ErrMsg);END CATCH', @database_name = N'master', @flags = 0; IF @ReturnCode <> 0 BEGIN RAISERROR(N'添加作业步骤失败,返回码:%d',16,1,@ReturnCode); END PRINT N'已添加作业执行步骤'; -- 配置作业调度 EXEC @ReturnCode = msdb.dbo.sp_add_jobschedule @job_id = @JobId, @name = N'$SCHEDULE_NAME', @enabled = 1, @freq_type = 8, @freq_interval = 127, @freq_subday_type = 1, @freq_subday_interval = 0, @freq_relative_interval = 0, @freq_recurrence_factor = 1, @active_start_date = CONVERT(INT, REPLACE(CONVERT(VARCHAR(10), GETDATE(), 112), '-', '')), @active_end_date=99991231, @active_start_time=$DAILY_EXEC_TIME, @active_end_time=235959;IF @ReturnCode<>0BEGIN RAISERROR(N'配置作业调度失败,返回码:%d',16,1,@ReturnCode);END PRINT N'已配置作业调度:每日$DAILY_EXEC_TIME执行';-- 关联作业到本地服务器(Linux下SQL Server实例默认名为MSSQLSERVER) EXEC @ReturnCode=msdb.dbo.sp_add_jobserver @job_id=@JobId, @server_name=N'(local)';IF @ReturnCode<>0BEGIN RAISERROR(N'关联作业到服务器失败,返回码:%d',16,1,@ReturnCode);END PRINT N'已将作业关联到本地服务器';COMMIT TRANSACTION;PRINT N'============================================';PRINT N'作业【$JOB_NAME】创建成功!';PRINT N'============================================';END TRY BEGIN CATCH IF @@TRANCOUNT>0ROLLBACK TRANSACTION;DECLARE @ErrorMessage NVARCHAR(4000)=ERROR_MESSAGE(), @ErrorSeverity INT=ERROR_SEVERITY(), @ErrorState INT=ERROR_STATE();RAISERROR(N'创建作业失败:%s',@ErrorSeverity,@ErrorState,@ErrorMessage);END CATCH SET NOCOUNT OFF;EOF)# ======================== 执行TSQL脚本 ========================echo"【信息】开始执行TSQL脚本,创建自动收缩日志作业..."/opt/mssql-tools/bin/sqlcmd -S"$SQL_SERVER"-U"$SQL_USER"-P"$SQL_PWD"-Q"$TSQL_SCRIPT"# 检查执行结果if[$?-eq0];thenecho"【成功】作业创建脚本执行完成!"echo"【提示】可通过以下命令查看作业:"echo" /opt/mssql-tools/bin/sqlcmd -S$SQL_SERVER-U$SQL_USER-P$SQL_PWD-Q 'SELECT name, enabled FROM msdb.dbo.sysjobs WHERE name = N''$JOB_NAME'';'"echo"【提示】查看作业执行历史:"echo" /opt/mssql-tools/bin/sqlcmd -S$SQL_SERVER-U$SQL_USER-P$SQL_PWD-Q 'EXEC msdb.dbo.sp_help_jobhistory @job_name = N''$JOB_NAME'';'"elseecho"【错误】作业创建脚本执行失败!"exit1fi

二、使用步骤

1. 前置准备

  • 确保Linux服务器已安装SQL Server并启动服务;
  • 安装sqlcmd工具:
    • Debian/Ubuntu:sudo apt-get update && sudo apt-get install -y mssql-tools unixodbc-dev
    • RHEL/CentOS:sudo yum install -y mssql-tools unixODBC-devel
  • master库创建dbo.ShrinkUser_DATABASESLogFile存储过程(核心收缩逻辑);
  • 创建低权限SQL运维账户(可选,替代sa)。

2. 脚本部署与执行

# 1. 将脚本保存为sqlserver_shrink_log_job.shvimsqlserver_shrink_log_job.sh# 2. 添加执行权限chmod+x sqlserver_shrink_log_job.sh# 3. 设置SQL密码环境变量(关键:避免硬编码)exportSQL_PWD="你的SQL账户密码"# 4. 执行脚本./sqlserver_shrink_log_job.sh

3. 验证作业创建结果

# 查看创建的作业/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P"$SQL_PWD"-Q"SELECT name, enabled FROM msdb.dbo.sysjobs WHERE name = N'ShrinkFile_DB_Logfile';"# 手动执行作业(测试)/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P"$SQL_PWD"-Q"EXEC msdb.dbo.sp_start_job @job_name = N'ShrinkFile_DB_Logfile';"# 查看作业执行历史/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P"$SQL_PWD"-Q"EXEC msdb.dbo.sp_help_jobhistory @job_name = N'ShrinkFile_DB_Logfile';"

三、重要注意事项

1. 安全规范

  • 禁止硬编码密码:永远不要将SQL密码直接写入脚本,通过环境变量或配置文件传入;
  • 最小权限原则:避免使用sa账户,创建专门的运维账户(授予SQLAgentOperatorRoledb_owner(master库)等最小权限);
  • 脚本权限:限制脚本的读取权限(chmod 700 sqlserver_shrink_log_job.sh),避免密码泄露。

2. 性能与业务风险

  • 收缩日志的适用场景:仅用于日志异常增长的应急场景,不要作为常规运维手段;
  • 完整恢复模式处理:若数据库为完整恢复模式,需在收缩前执行日志备份(BACKUP LOG),否则收缩无效;
  • 避免碎片化:频繁收缩会导致日志文件碎片化,建议收缩后调整日志文件的自动增长规则(如按固定大小增长,而非百分比)。

3. 运维监控

  • 定期检查作业执行历史,确认收缩逻辑正常运行;
  • 监控数据库日志文件大小,从根源解决增长问题(如优化长事务、调整恢复模式、配置定时日志备份);
  • Linux下可通过cron定时检查作业状态(可选)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/22 19:19:22

【Java毕设全套源码+文档】基于Java的游戏账号估价交易平台的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/4/23 13:43:47

【强烈收藏】大模型RAG技术入门到精通:解决AI“幻觉“的终极方案

RAG技术是将信息检索与文本生成相结合的创新技术&#xff0c;通过引入外部知识库提升大模型效果。文章详细介绍了RAG的定义、原理、系统架构和工作流程&#xff0c;从朴素RAG到GraphRAG的发展历程&#xff0c;以及提高答案准确性、实时更新知识等优势。同时分析了检索质量、计算…

作者头像 李华
网站建设 2026/4/23 13:44:13

【Vue.js:构建现代Web应用的渐进式框架--web技术栈】

一、Vue.js的核心哲学 1.1 渐进式框架设计 Vue.js最大的特色是其渐进式架构设计。与其他全功能框架不同&#xff0c;Vue允许开发者从核心库开始&#xff0c;根据项目需求逐步添加生态系统中的工具和功能&#xff1a; 核心库&#xff1a;声明式渲染和组件系统路由&#xff1a;Vu…

作者头像 李华
网站建设 2026/4/23 11:46:27

加密PDF解析的Dify内存占用(专家级调优指南,仅限内部分享)

第一章&#xff1a;加密PDF解析的Dify内存占用问题综述 在使用 Dify 平台处理加密 PDF 文件的解析任务时&#xff0c;部分用户反馈系统出现显著的内存占用上升现象&#xff0c;严重时可导致服务响应延迟甚至进程崩溃。该问题主要出现在高并发或大文件批量处理场景中&#xff0c…

作者头像 李华
网站建设 2026/4/23 11:47:09

Pytest实践:Python测试技术基础知识

一、简介 在软件开发领域&#xff0c;确保代码的正确性和稳健性至关重要。这就是软件测试发挥作用的地方。Python 是一种通用且广泛使用的编程语言&#xff0c;提供了大量的工具和库来帮助测试过程。 其中&#xff0c;Pytest就是一个很好用的测试框架&#xff0c;可以在 Pyth…

作者头像 李华
网站建设 2026/4/23 11:52:16

没有中兴的智谱,被民间华强北盯上了

开源之后&#xff0c;市场能拼出一部“AI手机”吗&#xff1f;作者|王浩然编辑|古廿最近智谱的广告出现在机场广告牌&#xff0c;打出了一整套AI叙事的新标签&#xff1a;“有的AI&#xff0c;提供情绪价值”“智谱AI&#xff0c;提供商业价值”。配合上醒目的LOGO&#xff0c;…

作者头像 李华