当前位置: 首页 > news >正文

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定时检查作业状态(可选)。
http://www.cnnetsun.cn/news/95817.html

相关文章:

  • 基于Java实现优雅关闭的规范化方案设计与实现
  • 时序数据战场巅峰对决:金仓数据库 VS InfluxDB深度解析
  • Windows任务管理器中CPU相关指标怎么看?
  • 【必藏】大模型入行晚了?现在就是黄金时机!小白到入门的完整路线
  • 系统思考与认知习惯
  • 速藏!2026年免费免版权音乐素材网站推荐!正规版权保障,商用无压力不侵权
  • 【数据分享】1951-2024年我国省市县三级逐日、逐月和逐年近地面气温数据(Shp/Excel格式)
  • 金融行业广告投放:在合规的赛道上,实现精准增长
  • 长安汽车11月销量28.3万辆,同比增长2.3%
  • 1688 商品详情接口深度解析:从百川签名突破到供应链数据重构
  • LobeChat心理情绪日记分析工具
  • 一文搞懂纸老虎-布隆过滤器
  • LobeChat周年庆感恩回馈活动
  • 运维系列数据库系列【仅供参考】:DM JOB作业的邮件发送
  • 当AI面临伦理投诉时,AI应用架构师该怎么办?这5个解决步骤
  • 主存编址是什么
  • Python 整合 Redis 哨兵(Sentinel)与集群(Cluster)实战指南
  • HLS技术的局限性说明
  • 水文监测站:水资源管理的“千里眼”与“顺风耳”
  • 白银波动幅度大于黄金的原因:市场规模与属性差异深度解析
  • 【2026版】Spring Boot面试题
  • 办公小程序开发----提高工作效率
  • Jmeter 命令行压测生成HTML测试报告
  • AI编程系列——mcp与skill
  • 技术文章大纲:当云原生遇见VMware
  • AI Agent开发全攻略:2025年核心技术栈与学习资源,从新手到专家的蜕变之路!
  • LobeChat实体抽取能力在CRM中的应用
  • Java毕设项目:基于springboot天气预报查询系统(源码+文档,讲解、调试运行,定制等)
  • Netcode for GameObjects Boss Room 多人RPG战斗(6)
  • Java毕设项目:基于JavaWeb的心聘求职平台的设计与实现(源码+文档,讲解、调试运行,定制等)