Restart指令-SQL Server在Linux重启离奇崩溃


故障解密:SQL Server在Linux的离奇崩溃——为什么重启服务器能解决而重启服务无效?

问题现象
  • 环境:CentOS 7 + SQL Server 2019
  • 异常表现:
    1. sudo systemctl restart mssql-server 后服务状态显示 active (running)
    2. 数分钟后服务自动崩溃
    3. 关键线索:重启整个操作系统后服务正常启动
    4. 日志报错:权限不够Access was denied无法打开"/var/log/messages" 读取数据
[root@xxx log]# sudo systemctl restart mssql-server
[root@xxx log]#  sudo systemctl status mssql-server.service 
● mssql-server.service - Microsoft SQL Server Database Engine
   Loaded: loaded (/usr/lib/systemd/system/mssql-server.service; enabled; vendor preset: disabled)
   Active: active (running) since 四 2025-08-21 19:11:20 CST; 3s ago
     Docs: https://docs.microsoft.com/en-us/sql/linux
 Main PID: 808567 (handle-crash.sh)
    Tasks: 36
   CGroup: /system.slice/mssql-server.service
           ├─808567 /bin/bash /opt/mssql/bin/handle-crash.sh sqlservr 808570 /opt/mssql/bin /var/opt/m
           ├─808570 /opt/mssql/bin/sqlservr
           └─808976 /opt/mssql/bin/paldumper -p 808570 -d miniplus -o /var/opt/mssql/log/core.sqlservr

821 19:11:23 xxx sqlservr[808567]: Users in the 'systemd-journal' group can see all messa
821 19:11:23 xxx sqlservr[808567]: turn off this notice.
821 19:11:23 xxx sqlservr[808567]: No journal files were opened due to insufficient permi
821 19:11:23 xxx sqlservr[808567]: Hint: You are currently not seeing messages from other
821 19:11:23 xxx sqlservr[808567]: Users in the 'systemd-journal' group can see all messa
821 19:11:23 xxx sqlservr[808567]: turn off this notice.
821 19:11:23 xxx sqlservr[808567]: No journal files were opened due to insufficient permi
821 19:11:23 xxx sqlservr[808567]: /usr/bin/tail: 无法打开"/var/log/messages" 读取数据: 权
821 19:11:23 xxx sqlservr[808567]: 2025年 08月 21日 星期四 19:11:23 CST Capturing program
821 19:11:24 xxx sqlservr[808567]: 2025年 08月 21日 星期四 19:11:24 CST Attempting to cap
Hint: Some lines were ellipsized, use -l to show in full.
深度分析
1. 表面假象:权限问题并非真凶

初始日志显示文件访问权限错误(如 /var/log/messages 不可读),但这只是伴生现象。根本问题在于:

Aug 21 19:06:55 xxx sqlservr: 
Message: Access was denied setting up the persistent registry: \SystemRoot\licensing.hiv.
Last errno: 13 (权限不够)

👉 核心根因
SQL Server在Linux通过paldumper组件模拟Windows注册表机制。启动时需访问持久化注册表文件 licensing.hiv,而该文件因权限或锁冲突导致访问失败,触发进程级致命错误(Fatal Error)。

2. 重启服务器的“魔法”解密

为何重启操作系统能解决问题?原因在于:

  • 残留进程:异常退出的sqlservr进程未完全释放资源
  • 文件锁未释放licensing.hiv或其锁文件被僵尸进程占用
  • 内存脏数据:内核文件系统缓存中存在损坏的元数据
    重启操作系统会强制清理所有进程句柄、文件锁和缓存,实现“干净启动”。
3. 重启服务为何无效?

systemctl restart 仅重启服务进程,但:

  • 无法清除内核持有的文件锁
  • 无法终止第三方驱动残留资源(如日志中disksbd_linux模块报错)
  • 无法重置系统级缓存
终极解决方案
步骤1:彻底清理残留进程
# 停止服务
sudo systemctl stop mssql-server

# 确认无残留进程(重点检查子进程)
ps -ef | grep -E "sqlservr|paldumper"

# 强制终止所有相关进程
sudo pkill -9 -f "sqlservr"
步骤2:修复文件权限
# 确保mssql用户拥有数据目录权限
sudo chown -R mssql:mssql /var/opt/mssql/
sudo chmod -R u+rwX /var/opt/mssql/

# 检查注册表文件状态
ls -l /var/opt/mssql/.system/system/registry/
步骤3:预防性配置
# 1. 增加日志权限(避免伴生错误)
sudo usermod -aG adm,systemd-journal mssql

# 2. 配置systemd服务自动清理(编辑服务文件)
sudo vi /usr/lib/systemd/system/mssql-server.service

# 在 [Service] 段添加:
Restart=on-failure
RestartSec=30s
KillMode=process
技术原理深度解读
  1. Linux注册表模拟机制
    SQL Server通过/opt/mssql/lib/libregistry.so实现注册表仿真,licensing.hiv存储许可证信息。该文件损坏或锁冲突将导致启动崩溃。

  2. SIGKILL与资源释放
    pkill -9发送SIGKILL信号强制终止进程,但Linux内核可能延迟释放文件锁(尤其NFS场景)。只有重启操作系统可彻底重置内核状态。

  3. 第三方驱动干扰
    日志中disksbd_linux模块报错表明存储层异常,可能干扰文件访问:

    disksbd_linux ERROR [fdisk_manager_thread]:get len invalid 0 72
    

    建议排查存储驱动兼容性。

经验总结
  • 典型误区: 将权限问题视为根本原因,忽略注册表文件的核心作用
  • 快速定位技巧
    sudo grep "fatal error" /var/opt/mssql/log/errorlog 直接锁定崩溃事件
  • 预防建议
    • 定期检查/var/opt/mssql/.system目录权限
    • 启用SQL Server错误日志轮换:sudo /opt/mssql/bin/mssql-conf set filelocation.errorlogfile /var/log/mssql/errorlog
    • 避免非正常关机导致文件锁残留
  • 注意:
    • 日志目录
 	
[root@xxx log]# pwd
/var/opt/mssql/log
[root@xxx log]# ll -lt
总用量 913712
-rw-rw---- 1 mssql mssql   830290 822 17:00 sqlagent.2
-rw-r----- 1 root  root       500 822 16:56 sqlagent.out
-rw-r----- 1 mssql mssql      113 822 16:56 sqlagentstartup.log
-rw-r----- 1 root  root       500 821 22:31 sqlagent.1
[root@xxx log]# cd /data/db/mssql/logs
[root@xxx logs]# ll -lt
总用量 840052
-rw-rw---- 1 mssql mssql    404992 822 17:07 log_174477.trc
-rw-rw---- 1 mssql mssql  14301184 822 17:05 system_health_0_134002485750360000.xel
-rw-rw---- 1 mssql mssql   1048576 822 17:02 log_174476.trc
-rw-rw---- 1 mssql mssql   1048576 822 16:57 log_174475.trc
-rw-rw---- 1 mssql mssql   1048576 822 16:52 log_174474.trc
-rw-rw---- 1 mssql mssql   1048576 822 16:47 log_174473.trc
-rw-rw---- 1 mssql mssql     22607 822 12:38 errorlog
-rw-rw---- 1 mssql mssql     34255 822 12:38 errorlog.loc
-rw-rw---- 1 mssql mssql     70144 821 19:16 HkEngineEventFile_0_134002485745220000.xel
-rw-rw---- 1 mssql mssql  83784192 821 19:06 system_health_0_133997592207460000.xel
-rw-rw---- 1 mssql mssql    145523 821 19:06 errorlog.1
-rw-rw---- 1 mssql mssql    156792 821 19:06 errorlog1.loc

# 配置文件路径
[root@xxx ~]# cd /var/opt/mssql
[root@xxx mssql]# ls
data  log  mssql.conf
# 默认log跟mssql.conf是同个目录下。否则需查看mssql.conf


本文解决的不仅是技术问题,更是Linux与Windows混合架构下的典型冲突案例。掌握底层机制,方能破局表象迷惑。


附录:排查命令速查表
目的命令
检查崩溃日志sudo grep -A 50 "fatal error" /var/opt/mssql/log/errorlog
确认文件锁sudo lsof /var/opt/mssql/.system/system/registry/licensing.hiv
内核级错误`sudo dmesg -T
权限修复sudo find /var/opt/mssql -type d -exec chmod 750 {} \;

本文适用于:
SQL Server 2017+ on RHEL/CentOS 7/8,Ubuntu 16.04+
延伸阅读:
https://learn.microsoft.com/zh-cn/sql/linux/sql-server-linux-troubleshooting-guide

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值