2026年CentOS上SQL Server日志查看与管理完整指南(2026)

一、SQL Server on Linux日志概述

SQL Server在Linux环境下的日志系统与Windows版本保持一致,主要包括错误日志、代理日志和SQL Server日志(包含Windows应用程序日志)。这些日志文件对于故障排查、性能监控和安全审计至关重要。

SQL Server日志类型
错误日志(Error Log):记录启动、关闭、严重错误信息
SQL Server日志:记录数据库引擎运行事件
代理日志(Agent Log):记录作业执行、调度信息
Windows事件日志:系统级日志和应用程序日志
Windows应用程序日志:与SQL Server相关的Windows事件

日志默认位置
– 错误日志:/var/opt/mssql/log/errorlog
– SQL Server日志:/var/opt/mssql/log/sqlservr.log
– 代理日志:/var/opt/mssql/log/sqlagent.log
– 备份日志:/var/opt/mssql/log/backup.log

二、查看SQL Server错误日志

2.1 使用系统命令查看

查看错误日志文件

# 查看最新错误日志
cat /var/opt/mssql/log/errorlog

# 查看最近20行
tail -20 /var/opt/mssql/log/errorlog

# 实时跟踪日志
tail -f /var/opt/mssql/log/errorlog

# 统计日志行数
wc -l /var/opt/mssql/log/errorlog

错误日志格式示例

2026-05-11 09:30:15.23      服务器      主题: 服务器进程 1934 已启动。
2026-05-11 09:30:15.24      服务器      主题: 服务器正在监听 [ 0.0.0.0 <IPv4> 1433]。
2026-05-11 09:30:15.24      服务器      主题: 服务器正在监听 [ :: <IPv6> 1433]。
2026-05-11 09:30:15.28      服务器      主题: SQL Server 正在按以下规范运行: 
                                    copyright (C) Microsoft Corporation.  All rights reserved.
                                    Server process ID is 1934.

2.2 使用sqlcmd查询日志

通过T-SQL查询日志

sqlcmd -S localhost -U sa -P "YourStrong@Password" -Q "
EXEC sys.xp_readerrorlog;
" -C

查询特定类型日志

-- 查询错误日志(参数0)
EXEC sys.xp_readerrorlog 0, 1;

-- 查询SQL Server日志(参数1)
EXEC sys.xp_readerrorlog 1, 1;

-- 搜索包含"error"的日志条目
EXEC sys.xp_readerrorlog 0, 1, 'error';

-- 搜索特定日期范围的日志
EXEC sys.xp_readerrorlog 0, 1, NULL, '2026-05-01', '2026-05-11';

查看日志文件列表

-- 查看当前归档的日志文件
EXEC sys.sp_enumerrorlogs;
GO

-- 输出示例:
-- Archive #   Date          Log File Size(KB)
-- --------   ----------    ---------------
-- 0          2026-05-11    1024
-- 1          2026-05-10    2048
-- 2          2026-05-09    1536

2.3 常用日志查询示例

查询最近24小时的错误

EXEC sys.xp_readerrorlog 0, 1, NULL, DATEADD(day, -1, GETDATE()), NULL;

查询登录失败记录

EXEC sys.xp_readerrorlog 0, 1, '登录失败';
EXEC sys.xp_readerrorlog 0, 1, 'failed';

查询连接相关事件

-- 查看成功连接
EXEC sys.xp_readerrorlog 0, 1, '连接已成功';

-- 查看断开连接
EXEC sys.xp_readerrorlog 0, 1, '连接已断开';

-- 查看超时
EXEC sys.xp_readerrorlog 0, 1, '超时';

三、SQL Server日志配置

3.1 配置日志轮换

# 查看当前日志配置
sudo /opt/mssql/bin/mssql-conf get log

# 设置错误日志轮换(每天一个新文件)
sudo /opt/mssql/bin/mssql-conf set log.sequencing 1

# 设置最大日志文件数量
sudo /opt/mssql/bin/mssql-conf set logfiles.maxsize 30

# 重启SQL Server生效
sudo systemctl restart mssql-server

手动轮换日志

# 重命名当前错误日志
sudo mv /var/opt/mssql/log/errorlog /var/opt/mssql/log/errorlog.$(date +%Y%m%d_%H%M%S)

# 重启SQL Server创建新日志文件
sudo systemctl restart mssql-server

# 查看新日志文件
ls -la /var/opt/mssql/log/

3.2 配置日志详细程度

-- 查看当前错误日志级别
DBCC TRACESTATUS(3604);

-- 设置错误日志详细程度
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;

-- 查看trace标志
EXEC sp_configure;

3.3 配置Windows事件日志

# 查看Windows应用程序日志
sudo journalctl -u mssql-server --since "1 hour ago"

# 实时跟踪日志
sudo journalctl -u mssql-server -f

# 保存日志到文件
sudo journalctl -u mssql-server > /tmp/mssql_journal.log

四、日志分析与故障排查

4.1 常见错误分析与解决方案

启动错误

错误:SQL Server无法启动
原因:内存不足、端口被占用、配置文件损坏
解决方案:
1. 检查内存:free -h
2. 检查端口:ss -tlnp | grep 1433
3. 修复配置:sudo /opt/mssql/bin/mssql-conf setup

连接错误

错误:无法连接到SQL Server
原因:防火墙未开放、服务未启动、网络问题
解决方案:
1. 检查服务状态:sudo systemctl status mssql-server
2. 开放防火墙:sudo firewall-cmd --add-port=1433/tcp --permanent
3. 测试连接:sqlcmd -S localhost -U sa -P "Password"

权限错误

错误:无法访问日志文件
原因:文件权限不足、用户不属于mssql组
解决方案:
1. 添加用户到mssql组:sudo usermod -aG mssql $USER
2. 修改文件权限:sudo chmod 644 /var/opt/mssql/log/errorlog
3. 重新登录生效

4.2 日志分析脚本

自动化日志分析脚本

#!/bin/bash
# analyze_sqlserver_logs.sh - SQL Server日志分析脚本

LOG_DIR="/var/opt/mssql/log"
REPORT_FILE="/tmp/mssql_log_report_$(date +%Y%m%d_%H%M%S).txt"
SA_PASSWORD="YourStrong@Password"

echo "=== SQL Server日志分析报告 ===" > $REPORT_FILE
echo "分析时间:$(date)" >> $REPORT_FILE
echo "" >> $REPORT_FILE

# 1. 错误统计
echo "【错误统计】" >> $REPORT_FILE
echo "错误日志文件大小:$(du -h $LOG_DIR/errorlog | cut -f1)" >> $REPORT_FILE
echo "最近错误数量:$(grep -c '错误\|Error\|error' $LOG_DIR/errorlog 2>/dev/null || echo 0)" >> $REPORT_FILE
echo "" >> $REPORT_FILE

# 2. 登录统计
echo "【登录统计】" >> $REPORT_FILE
echo "成功登录次数:$(grep -c '登录已成功\|Login succeeded' $LOG_DIR/errorlog 2>/dev/null || echo 0)" >> $REPORT_FILE
echo "失败登录次数:$(grep -c '登录失败\|Login failed' $LOG_DIR/errorlog 2>/dev/null || echo 0)" >> $REPORT_FILE
echo "" >> $REPORT_FILE

# 3. 连接统计
echo "【连接统计】" >> $REPORT_FILE
echo "当前连接数:$(sqlcmd -S localhost -U sa -P "$SA_PASSWORD" -Q "SELECT COUNT(*) FROM sys.dm_exec_sessions WHERE is_user_process=1" -h -1 -C 2>/dev/null | head -2)" >> $REPORT_FILE
echo "" >> $REPORT_FILE

# 4. 最近错误
echo "【最近10条错误】" >> $REPORT_FILE
tail -50 $LOG_DIR/errorlog | grep -E '错误|Error' >> $REPORT_FILE 2>/dev/null || echo "无错误记录" >> $REPORT_FILE

echo ""
echo "报告已保存到:$REPORT_FILE"
cat $REPORT_FILE

4.3 实时监控脚本

实时错误监控脚本

#!/bin/bash
# monitor_sqlserver_errors.sh - SQL Server实时错误监控

LOG_FILE="/var/opt/mssql/log/errorlog"
ALERT_EMAIL="admin@example.com"
KEYWORDS="错误|Error|严重|critical|警告|Warning"

# 记录上次检查位置
POSITION_FILE="/tmp/mssql_log_monitor_pos"

if [ -f $POSITION_FILE ]; then
    LAST_POS=$(cat $POSITION_FILE)
else
    LAST_POS=0
fi

# 获取当前文件大小
CURRENT_SIZE=$(stat -c%s $LOG_FILE)

# 如果日志文件被轮换,从头开始
if [ $CURRENT_SIZE -lt $LAST_POS ]; then
    LAST_POS=0
fi

# 读取新内容
NEW_CONTENT=$(tail -c $(($CURRENT_SIZE - $LAST_POS)) $LOG_FILE 2>/dev/null)

# 检查关键词
if echo "$NEW_CONTENT" | grep -qE "$KEYWORDS"; then
    echo "发现SQL Server错误或警告:" | mail -s "SQL Server监控告警" $ALERT_EMAIL
    echo "$NEW_CONTENT" | grep -E "$KEYWORDS" | tail -20 | mail -s "SQL Server监控告警" $ALERT_EMAIL
fi

# 更新位置
echo $CURRENT_SIZE > $POSITION_FILE

echo "监控完成:$(date)"

五、日志备份与归档

5.1 日志备份脚本

#!/bin/bash
# backup_sqlserver_logs.sh - SQL Server日志备份脚本

BACKUP_DIR="/var/opt/mssql/backup/logs"
LOG_DIR="/var/opt/mssql/log"
DATE=$(date +%Y%m%d)
DAYS_KEEP=30

# 创建备份目录
mkdir -p $BACKUP_DIR

# 备份错误日志
tar -czf $BACKUP_DIR/errorlog_$DATE.tar.gz $LOG_DIR/errorlog* 2>/dev/null

# 备份SQL Server日志
tar -czf $BACKUP_DIR/sqlservr_$DATE.tar.gz $LOG_DIR/sqlservr*.log 2>/dev/null

# 备份代理日志
tar -czf $BACKUP_DIR/sqlagent_$DATE.tar.gz $LOG_DIR/sqlagent*.log 2>/dev/null

# 清理过期备份
find $BACKUP_DIR -name "*.tar.gz" -mtime +$DAYS_KEEP -delete

# 输出备份信息
echo "=== 日志备份完成 ==="
echo "备份时间:$(date)"
echo "备份目录:$BACKUP_DIR"
echo "备份文件:"
ls -lh $BACKUP_DIR | grep $DATE

5.2 日志归档策略

配置日志归档

-- 创建日志归档存储过程
CREATE PROCEDURE sp_archive_old_logs
AS
BEGIN
    DECLARE @old_date DATETIME = DATEADD(day, -30, GETDATE());

    -- 删除30天前的归档日志文件
    -- 注意:此操作需要谨慎执行
    EXEC xp_delete_file 0, '/var/opt/mssql/log/archive', 'log', @old_date;
END;
GO

-- 创建每日归档作业
EXEC msdb.dbo.sp_add_job @job_name = N'归档旧日志',
                         @enabled = 1,
                         @description = N'归档SQL Server旧日志文件';

EXEC msdb.dbo.sp_add_jobstep @job_name = N'归档旧日志',
                              @step_name = N'执行归档',
                              @subsystem = N'TSQL',
                              @command = N'EXEC sp_archive_old_logs';

六、日志与安全审计

6.1 启用审计日志

# 创建审计目录
sudo mkdir -p /var/opt/mssql/audit

# 配置SQL Server审计
sqlcmd -S localhost -U sa -P "YourStrong@Password" -Q "
CREATE SERVER AUDIT [SecurityAudit]
TO FILE (FILEPATH = '/var/opt/mssql/audit/', MAXSIZE = 100 MB)
WITH (ON_FAILURE = CONTINUE);

CREATE SERVER AUDIT SPECIFICATION [LoginAudit]
FOR SERVER AUDIT [SecurityAudit]
ADD (SUCCESSFUL_LOGIN_GROUP),
ADD (FAILED_LOGIN_GROUP);

ALTER SERVER AUDIT [SecurityAudit] WITH (STATE = ON);
ALTER SERVER AUDIT SPECIFICATION [LoginAudit] WITH (STATE = ON);
" -C

6.2 查询审计日志

-- 查看登录成功记录
SELECT 
    event_time,
    succeeded,
    server_principal_name,
    client_ip,
    session_id
FROM sys.fn_get_audit_file ('/var/opt/mssql/audit/*.sqlaudit', NULL, NULL)
WHERE succeeded = 1
ORDER BY event_time DESC;

-- 查看登录失败记录
SELECT 
    event_time,
    succeeded,
    server_principal_name,
    client_ip,
    session_id
FROM sys.fn_get_audit_file ('/var/opt/mssql/audit/*.sqlaudit', NULL, NULL)
WHERE succeeded = 0
ORDER BY event_time DESC;

6.3 定期安全检查

-- 检查登录失败次数过多的账户
SELECT 
    server_principal_name,
    COUNT(*) AS failure_count,
    MIN(event_time) AS first_failure,
    MAX(event_time) AS last_failure
FROM sys.fn_get_audit_file ('/var/opt/mssql/audit/*.sqlaudit', NULL, NULL)
WHERE succeeded = 0
GROUP BY server_principal_name
HAVING COUNT(*) > 10
ORDER BY failure_count DESC;

七、使用第三方工具分析日志

7.1 logstash配置

# 安装logstash
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
cat << EOF | sudo tee /etc/yum.repos.d/logstash.repo
[logstash-7.x]
name=Elastic Logstash 7.x
baseurl=https://artifacts.elastic.co/downloads/logstash/logstash-7.x.rpm
enabled=1
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
EOF
sudo yum install -y logstash

# 配置logstash输入
cat << EOF | sudo tee /etc/logstash/conf.d/mssql-input.conf
input {
  file {
    path => "/var/opt/mssql/log/errorlog"
    start_position => "beginning"
    sincedb_path => "/var/lib/logstash/sincedb_mssql"
    codec => plain {
      charset => "UTF-8"
    }
  }
}
output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "mssql-logs-%{+YYYY.MM.dd}"
  }
}
EOF

7.2 Elasticsearch查询示例

# 查询最近1小时的错误
curl -X GET "localhost:9200/mssql-logs-*/_search?q=error&size=20"

# 查询特定时间范围的日志
curl -X POST "localhost:9200/mssql-logs-*/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "now-1h",
        "lte": "now"
      }
    }
  }
}'

八、性能相关日志分析

8.1 查询性能日志

-- 启用查询统计
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'query_store', 1;
RECONFIGURE;

-- 查看慢查询
SELECT 
    q.avg_duration,
    q.avg_cpu_time,
    q.avg_logical_io_reads,
    q.query_text
FROM sys.query_store_runtime_stats r
JOIN sys.query_store_query q ON r.query_id = q.query_id
ORDER BY avg_duration DESC;

8.2 死锁日志分析

-- 查看最近死锁
SELECT 
    XEvent.query(XML)'
    FROM sys.dm_xe_session_targets t
    JOIN sys.dm_xe_sessions s ON t.event_session_address = s.address
    WHERE t.target_name = 'event_file'
    AND s.name = 'system_health';

8.3 等待统计日志

-- 记录等待统计到日志表
CREATE TABLE WaitStatsLog (
    ID INT IDENTITY PRIMARY KEY,
    CaptureTime DATETIME DEFAULT GETDATE(),
    WaitType NVARCHAR(60),
    WaitingTasks INT,
    WaitTimeMs BIGINT,
    SignalWaitMs BIGINT
);

-- 创建定期记录作业
CREATE PROCEDURE CaptureWaitStats
AS
BEGIN
    INSERT INTO WaitStatsLog (WaitType, WaitingTasks, WaitTimeMs, SignalWaitMs)
    SELECT 
        wait_type,
        waiting_tasks_count,
        wait_time_ms,
        signal_wait_time_ms
    FROM sys.dm_os_wait_stats
    WHERE waiting_tasks_count > 0;
END;
GO

九、常见问题与解决方案

Q1:日志文件过大占用磁盘空间?

解决方案
1. 配置日志轮换
2. 定期归档和压缩旧日志
3. 删除不需要的历史日志

# 查看日志目录大小
du -sh /var/opt/mssql/log/*

# 压缩旧日志
find /var/opt/mssql/log -name "*.log.*" -mtime +7 -exec gzip {} \;

# 删除超过30天的日志归档
find /var/opt/mssql/log -name "errorlog.*" -mtime +30 -delete

Q2:无法读取日志文件权限不足?

解决方案
1. 将用户添加到mssql组
2. 修改日志文件权限
3. 使用sudo运行sqlcmd

# 添加当前用户到mssql组
sudo usermod -aG mssql $USER

# 修改日志文件权限
sudo chmod 640 /var/opt/mssql/log/errorlog
sudo chmod 640 /var/opt/mssql/log/sqlservr.log

# 重新登录使组权限生效
newgrp mssql

Q3:日志中乱码或中文字符无法识别?

解决方案
1. 设置正确的字符集
2. 使用UTF-8编码查看

# 查看当前编码
echo $LANG

# 设置UTF-8编码
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# 使用less查看(支持中文)
less /var/opt/mssql/log/errorlog

# 或使用iconv转换
iconv -f GBK -t UTF-8 errorlog.gbk > errorlog.utf8

Q4:日志查询很慢如何优化?

解决方案
1. 使用索引优化日志查询
2. 定期清理历史日志
3. 使用筛选条件减少返回数据

-- 创建索引优化日期查询
CREATE INDEX IX_ErrorLog_Date ON ErrorLog(EventTime);

-- 使用筛选条件
EXEC sys.xp_readerrorlog 0, 1, NULL, '2026-05-01', '2026-05-11';

十、总结

CentOS上SQL Server日志查看与管理的关键要点:

  • 日志位置/var/opt/mssql/log/ 目录下
  • 查看方式:命令行工具、sqlcmd、T-SQL存储过程
  • 配置管理:日志轮换、文件大小控制、定期归档
  • 故障排查:错误分析、性能监控、安全审计
  • 自动化:脚本监控、定期报告、告警通知
  • 安全:审计日志、登录记录、权限控制

掌握这些日志管理技巧,可以快速定位和解决SQL Server在Linux环境下的各种问题。

本文基于SQL Server 2022和CentOS Stream 9编写,适用于CentOS 7+/RHEL 7+/CentOS Stream环境。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注