故障解密:SQL Server在Linux的离奇崩溃——为什么重启服务器能解决而重启服务无效?
问题现象
- 环境:CentOS 7 + SQL Server 2019
 - 异常表现:
sudo systemctl restart mssql-server后服务状态显示active (running)- 数分钟后服务自动崩溃
 - 关键线索:重启整个操作系统后服务正常启动
 - 日志报错:
权限不够、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
8月 21 19:11:23 xxx sqlservr[808567]: Users in the 'systemd-journal' group can see all messa
8月 21 19:11:23 xxx sqlservr[808567]: turn off this notice.
8月 21 19:11:23 xxx sqlservr[808567]: No journal files were opened due to insufficient permi
8月 21 19:11:23 xxx sqlservr[808567]: Hint: You are currently not seeing messages from other
8月 21 19:11:23 xxx sqlservr[808567]: Users in the 'systemd-journal' group can see all messa
8月 21 19:11:23 xxx sqlservr[808567]: turn off this notice.
8月 21 19:11:23 xxx sqlservr[808567]: No journal files were opened due to insufficient permi
8月 21 19:11:23 xxx sqlservr[808567]: /usr/bin/tail: 无法打开"/var/log/messages" 读取数据: 权
8月 21 19:11:23 xxx sqlservr[808567]: 2025年 08月 21日 星期四 19:11:23 CST Capturing program
8月 21 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
技术原理深度解读
- 
Linux注册表模拟机制
SQL Server通过/opt/mssql/lib/libregistry.so实现注册表仿真,licensing.hiv存储许可证信息。该文件损坏或锁冲突将导致启动崩溃。 - 
SIGKILL与资源释放
pkill -9发送SIGKILL信号强制终止进程,但Linux内核可能延迟释放文件锁(尤其NFS场景)。只有重启操作系统可彻底重置内核状态。 - 
第三方驱动干扰
日志中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 8月  22 17:00 sqlagent.2
-rw-r----- 1 root  root       500 8月  22 16:56 sqlagent.out
-rw-r----- 1 mssql mssql      113 8月  22 16:56 sqlagentstartup.log
-rw-r----- 1 root  root       500 8月  21 22:31 sqlagent.1
[root@xxx log]# cd /data/db/mssql/logs
[root@xxx logs]# ll -lt
总用量 840052
-rw-rw---- 1 mssql mssql    404992 8月  22 17:07 log_174477.trc
-rw-rw---- 1 mssql mssql  14301184 8月  22 17:05 system_health_0_134002485750360000.xel
-rw-rw---- 1 mssql mssql   1048576 8月  22 17:02 log_174476.trc
-rw-rw---- 1 mssql mssql   1048576 8月  22 16:57 log_174475.trc
-rw-rw---- 1 mssql mssql   1048576 8月  22 16:52 log_174474.trc
-rw-rw---- 1 mssql mssql   1048576 8月  22 16:47 log_174473.trc
-rw-rw---- 1 mssql mssql     22607 8月  22 12:38 errorlog
-rw-rw---- 1 mssql mssql     34255 8月  22 12:38 errorlog.loc
-rw-rw---- 1 mssql mssql     70144 8月  21 19:16 HkEngineEventFile_0_134002485745220000.xel
-rw-rw---- 1 mssql mssql  83784192 8月  21 19:06 system_health_0_133997592207460000.xel
-rw-rw---- 1 mssql mssql    145523 8月  21 19:06 errorlog.1
-rw-rw---- 1 mssql mssql    156792 8月  21 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
                  
                  
                  
                  
                            
                            
                    
      
          
                
                
                
                
              
                
                
                
                
                
              
                
                
              
            
                  
被折叠的  条评论
		 为什么被折叠?
		 
		 
		
    
  
    
  
            


            