SQL Server 2019 on Linux:功能边界、安装配置与中文环境排障
你需要在 Linux 服务器上运行 SQL Server,或为开发环境统一数据库版本。SQL Server 2017 起官方支持 Linux,2019 版进一步缩小了与 Windows 版的功能差距。但这不等于「功能完全一致」——某些企业特性在 Linux 上不可用,安装后的初始化路径也与 Windows 不同。本文梳理 SQL Server 2019 on Linux 的支持边界、安装后必须做的 mssql-conf 配置、中文环境常见的排序规则坑,以及与托管版本的选型对照。
版本说明
原写于 2024-10,2026-09 重写。
基于 SQL Server 2019 (15.x) on Linux。微软官方文档显示,SQL Server 2019 在 Linux 上的功能集已接近 Windows 版,但仍有个别特性差异,详见「不支持的功能」章节。安装步骤适用于 RHEL/CentOS 7/8 和 Ubuntu 18.04/20.04/22.04。
# 1. 功能边界:Linux 版与 Windows 版的差异
SQL Server 2019 on Linux 已经支持核心数据库引擎、Always On 可用性组、事务复制等关键功能,但以下特性在 Linux 上仍不可用或有限制(来源:微软官方文档):
# 1.1 数据库引擎层的不支持项
| 特性 | Linux 状态 | 说明 |
|---|---|---|
| Merge Replication | 不支持 | 事务复制和快照复制已支持(2019 新增) |
| Stretch DB | 不支持 | SQL Server 2022 已弃用该功能 |
| 分布式查询(第三方 OLE DB) | 不支持 | 对 SQL Server 的链接服务器可用,其他数据源需用 PolyBase |
| CLR EXTERNAL_ACCESS/UNSAFE | 不支持 | 仅支持 SAFE 级别的 CLR 程序集 |
| Buffer Pool Extension | 不支持 | 内存扩展技术,Linux 版无此功能 |
| 备份到 URL(Page Blob) | 不支持 | 块 Blob(Block Blob)+ SAS 令牌方式可用 |
# 1.2 SQL Server Agent 的限制
SQL Server Agent 在 Linux 上存在子系统限制:
- 不支持的子系统:CmdExec、PowerShell、Queue Reader、SSIS、SSAS、SSRS
- 不支持的功能:警报(Alerts)、托管备份(Managed Backup)
这意味着依赖 PowerShell 或外部命令的维护计划需要重写为 Linux 原生方案(Bash + cron)。
# 1.3 高可用与安全的差异
| 特性 | Linux 状态 | 替代方案 |
|---|---|---|
| 数据库镜像 | 不支持(已弃用) | 使用 Always On 可用性组 |
| 可扩展密钥管理(EKM) | 不支持 | 使用 SQL Server 原生加密 |
| Windows 集成认证(链接服务器) | 不可用 | 使用 SQL Server 认证或证书认证 |
| FIPS 合规 | 不支持 | 需在应用层满足合规要求 |
# 1.4 分析服务与报表服务
- SQL Server Analysis Services (SSAS):Linux 版不支持
- SQL Server Reporting Services (SSRS):需运行在 Windows 上,但可以把报表目录数据库(catalog database)托管在 Linux 版的 SQL Server 上
总结:如果是纯 OLTP 场景、不需要 SSAS/SSRS,SQL Server on Linux 可以满足大部分需求。如果需要完整的 BI 栈或重度依赖 Agent PowerShell,则仍需 Windows 版。
# 2. 安装与基础配置
# 2.1 系统要求与前置检查
SQL Server 2019 on Linux 的系统要求(来源:微软官方文档):
- 内存:Express 版最低 512 MB,其他版本最低 2 GB(推荐 4 GB+)
- 磁盘:至少 6 GB 空闲空间,建议 XFS 或 ext4 文件系统
- CPU:x86-64 架构,频率 1.4 GHz 以上
- 操作系统:RHEL 7.3+、CentOS 7.3+、Ubuntu 18.04/20.04/22.04、SLES 12 SP2+
注意:容器镜像仅支持在 x86-64 Linux 主机上运行,Rosetta 2(ARM 转译)、QEMU 等模拟环境不受支持。
# 2.2 安装步骤(RHEL/CentOS)
# 1. 添加微软仓库
curl -o /etc/yum.repos.d/mssql-server.repo https://packages.microsoft.com/config/rhel/7/mssql-server-2019.repo
# 2. 安装 SQL Server
yum install -y mssql-server
# 3. 运行配置向导(设置 SA 密码、选择版本)
/opt/mssql/bin/mssql-conf setup
# 4. 验证服务状态
systemctl status mssql-server
2
3
4
5
6
7
8
9
10
11
安装完成后,SQL Server 服务默认监听 1433 端口(TCP)。
# 2.3 安装命令行工具
# 添加工具仓库
curl -o /etc/yum.repos.d/msprod.repo https://packages.microsoft.com/config/rhel/7/prod.repo
# 安装工具包
yum install -y mssql-tools unixODBC-devel
# 添加到 PATH
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# 测试连接
sqlcmd -S localhost -U SA -P '<YourStrong@Passw0rd>' -Q "SELECT @@VERSION"
2
3
4
5
6
7
8
9
10
11
12
预期输出
Microsoft SQL Server 2019 (RTM-CU32) (KB5037253) - 15.0.4455.4 (X64)
Jun 14 2024 15:51:20
Copyright (C) 2019 Microsoft Corporation
Developer Edition (64-bit) on Linux (CentOS Linux 7 (Core))
2
3
4
# 3. mssql-conf 关键配置
mssql-conf 是 SQL Server on Linux 的专用配置工具,相当于 Windows 版的 SQL Server Configuration Manager + 注册表编辑。关键配置项如下:
# 3.1 数据与日志目录
# 创建数据目录
mkdir -p /data/mssql/{data,log,backup}
chown -R mssql:mssql /data/mssql
# 设置默认路径
/opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /data/mssql/data
/opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /data/mssql/log
/opt/mssql/bin/mssql-conf set filelocation.defaultbackupdir /data/mssql/backup
# 重启生效
systemctl restart mssql-server
2
3
4
5
6
7
8
9
10
11
# 3.2 网络与端口
# 查看当前监听端口
/opt/mssql/bin/mssql-conf list | grep tcp
# 修改 TCP 端口(如改为 51433)
/opt/mssql/bin/mssql-conf set network.tcpport 51433
# 启用/禁用 TCP(默认启用)
/opt/mssql/bin/mssql-conf set network.tcpenabled true
2
3
4
5
6
7
8
# 3.3 排序规则(Collation)——中文环境关键
排序规则决定字符串比较、排序、大小写敏感性和字符集。Linux 版默认排序规则通常是 SQL_Latin1_General_CP1_CI_AS,对中文支持不佳。
# 查看当前排序规则
sqlcmd -S localhost -U SA -P '<password>' -Q "SELECT SERVERPROPERTY('Collation')"
# 修改服务器级排序规则(需重建系统数据库,会丢失已有数据!)
/opt/mssql/bin/mssql-conf set-collation Chinese_PRC_CI_AS
2
3
4
5
警告:修改排序规则需要重建 master、model、msdb 系统数据库,会删除所有用户数据库和登录信息。修改前必须备份。
推荐的中文排序规则:
Chinese_PRC_CI_AS:简体中文,不区分大小写,区分重音Chinese_PRC_BIN:简体中文,二进制比较(性能更好,但排序不按拼音)
如果服务器已有数据无法重建,可以在创建数据库时单独指定排序规则:
CREATE DATABASE [MyDB] COLLATE Chinese_PRC_CI_AS;
# 3.4 资源限制
# 设置最大内存(MB)
/opt/mssql/bin/mssql-conf set memory.memorylimitmb 8192
# 设置最大并行度(MAXDOP)
/opt/mssql/bin/mssql-conf set maxdop 4
# 启用/禁用 Agent(默认禁用)
/opt/mssql/bin/mssql-conf set sqlagent.enabled true
2
3
4
5
6
7
8
# 4. 中文环境常见坑
# 4.1 排序规则导致的查询异常
症状:WHERE name = '张三' 匹配不到,或 ORDER BY name 结果不按拼音排序。
根因:数据库或列使用了二进制排序规则(_BIN),或默认的 Latin1 规则不识别中文。
解决:
-- 查看数据库排序规则
SELECT name, collation_name FROM sys.databases WHERE name = 'YourDB';
-- 查看列级排序规则
SELECT name, collation_name FROM sys.columns
WHERE object_id = OBJECT_ID('YourTable') AND name = 'YourColumn';
-- 修改数据库排序规则(需独占访问)
ALTER DATABASE [YourDB] COLLATE Chinese_PRC_CI_AS;
2
3
4
5
6
7
8
9
# 4.2 字符集与客户端编码
Linux 终端默认编码通常是 UTF-8,但 sqlcmd 工具可能需要显式指定:
# 在 sqlcmd 前设置区域
export LANG=en_US.UTF-8
# 或使用 -u 参数启用 Unicode
sqlcmd -S localhost -U SA -P '<password>' -u -Q "SELECT N'中文测试'"
2
3
4
5
# 4.3 日志中的乱码
SQL Server Error Log 如果在终端显示乱码,通常是分页码表不匹配。建议通过 SQL 查询日志而非直接读文件:
-- 查看错误日志
EXEC sp_readerrorlog 0, 1, 'error';
2
# 5. Linux 特有优化与限制
# 5.1 内核参数调整
SQL Server on Linux 对文件描述符和共享内存有要求:
# /etc/sysctl.conf
vm.max_map_count = 262144 # 虚拟内存映射计数
fs.file-max = 65536 # 系统级文件句柄上限
# 应用
sysctl -p
2
3
4
5
6
# 5.2 透明大页(Transparent Hugepages)
微软建议禁用透明大页以避免内存分配延迟:
# 临时禁用
echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 永久禁用(/etc/rc.local 或 systemd)
2
3
4
# 5.3 文件系统选择
- 推荐:XFS(日志性能好,大数据文件效率高)
- 可用:ext4
- 不推荐:NFS(作为数据目录性能不稳定,除非使用特定挂载参数)
# 6. Always On 可用性组(Availability Group)配置
SQL Server on Linux 支持 Always On 可用性组,但与 Windows 版的关键差异在于:Linux 没有 Windows Server Failover Clustering (WSFC),因此使用 CLUSTER_TYPE = EXTERNAL,依赖外部集群管理器(如 Pacemaker)做故障仲裁,或使用 NONE 类型进行手动故障转移。
以下配置基于双节点架构:主节点 <db-master-01>,从节点 <db-slave-01>。
# 6.1 启用 HADR 功能
在两台服务器上分别执行:
# 启用 Always On 可用性组功能
sudo /opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
sudo systemctl restart mssql-server
# 安装高可用组件
sudo yum install -y mssql-server-ha
2
3
4
5
6
-hadr.hadrenabled 是 SQL Server 的核心参数,开启后数据库引擎才支持 AG 相关的动态管理视图和端点功能。
# 6.2 创建数据库镜像端点用户
为什么用证书而非账号密码:Linux 节点无法像 Windows 那样使用域账号做相互认证,因此采用证书认证——主从节点交换公钥证书,建立双向信任。这种方式不依赖外部 CA,完全由 SQL Server 自行管理。
在主节点执行:
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
CREATE LOGIN dbm_login WITH PASSWORD = '<Your_DBM_Password>';
CREATE USER dbm_user FOR LOGIN dbm_login;
"
2
3
4
# 6.3 在主节点创建证书
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Your_DBM_Password>';
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm';
BACKUP CERTIFICATE dbm_certificate
TO FILE = '/data/mssql/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/data/mssql/dbm_certificate.pvk',
ENCRYPTION BY PASSWORD = '<Your_DBM_Password>'
);
"
2
3
4
5
6
7
8
9
10
证书文件需要传输到从节点,用于建立信任关系。
# 6.4 将证书复制到从节点
sudo rsync -avz /data/mssql/dbm_certificate.* <db-slave-01>:/data/mssql/
确保从节点的 /data/mssql 目录对 mssql 用户可读。
# 6.5 在从节点创建证书
从节点使用主节点的证书创建对应的登录和用户:
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
CREATE LOGIN dbm_login WITH PASSWORD = '<Your_DBM_Password>';
CREATE USER dbm_user FOR LOGIN dbm_login;
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Your_DBM_Password>';
CREATE CERTIFICATE dbm_certificate
AUTHORIZATION dbm_user
FROM FILE = '/data/mssql/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/data/mssql/dbm_certificate.pvk',
DECRYPTION BY PASSWORD = '<Your_DBM_Password>'
);
"
2
3
4
5
6
7
8
9
10
11
12
13
此时主从节点的 dbm_login 通过同一证书建立了互信。
# 6.6 创建数据库镜像端点
在两台服务器上分别执行,创建 TCP 端点用于 AG 通信:
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
CREATE ENDPOINT [Hadr_endpoint]
AS TCP (LISTENER_PORT = 5022)
FOR DATABASE_MIRRORING (
ROLE = ALL,
AUTHENTICATION = CERTIFICATE dbm_certificate,
ENCRYPTION = REQUIRED ALGORITHM AES
);
ALTER ENDPOINT [Hadr_endpoint] STATE = STARTED;
GRANT CONNECT ON ENDPOINT::[Hadr_endpoint] TO [dbm_login];"
2
3
4
5
6
7
8
9
10
LISTENER_PORT = 5022:AG 通信的默认端口,与数据库服务 1433 分开ROLE = ALL:端点可用于主、从两种角色AUTHENTICATION = CERTIFICATE:使用刚创建的证书做双向认证
# 6.7 开放防火墙端口
sudo firewall-cmd --zone=public --add-port=5022/tcp --permanent
sudo firewall-cmd --reload
2
# 6.8 设置数据库为完整恢复模式
只有完整恢复模式的数据库才能加入 AG:
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
ALTER DATABASE [Your_Database_Name] SET RECOVERY FULL;
"
2
3
# 6.9 备份数据库并复制到从节点
# 主节点:完整备份
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
BACKUP DATABASE [Your_Database_Name]
TO DISK = '/data/mssql/backup/Your_Database_Name_full.bak';
"
# 主节点:日志备份
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
BACKUP LOG [Your_Database_Name]
TO DISK = '/data/mssql/backup/Your_Database_Name_log.bak';
"
# 复制到从节点
sudo rsync -avz /data/mssql/backup/Your_Database_Name_*.bak <db-slave-01>:/data/mssql/backup/
2
3
4
5
6
7
8
9
10
11
12
13
14
# 6.10 在从节点还原数据库(NORECOVERY 模式)
# 从节点:还原完整备份,指定 NORECOVERY(保留日志重放能力)
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
RESTORE DATABASE [Your_Database_Name]
FROM DISK = '/data/mssql/backup/Your_Database_Name_full.bak'
WITH NORECOVERY;
"
# 从节点:还原日志备份,同样指定 NORECOVERY
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
RESTORE LOG [Your_Database_Name]
FROM DISK = '/data/mssql/backup/Your_Database_Name_log.bak'
WITH NORECOVERY;
"
2
3
4
5
6
7
8
9
10
11
12
13
数据库处于 RESTORING 状态时,才能被加入 AG。
# 6.11 创建可用性组
在主节点创建 AG,指定 CLUSTER_TYPE = EXTERNAL:
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
CREATE AVAILABILITY GROUP [AG1]
WITH (
DB_FAILOVER = ON,
CLUSTER_TYPE = EXTERNAL
)
FOR REPLICA ON
N'<db-master-01>' WITH (
ENDPOINT_URL = N'TCP://<db-master-01>:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
),
N'<db-slave-01>' WITH (
ENDPOINT_URL = N'TCP://<db-slave-01>:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = EXTERNAL,
SEEDING_MODE = AUTOMATIC
);
"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
关键参数说明:
CLUSTER_TYPE = EXTERNAL:告知 SQL Server 使用外部集群管理器(如 Pacemaker)做仲裁,区别于 WSFCSEEDING_MODE = AUTOMATIC:自动种子同步,从节点会自动从主节点同步初始数据(要求从节点已还原到 NORECOVERY 状态)AVAILABILITY_MODE = SYNCHRONOUS_COMMIT:同步提交,保证主从数据一致,但会增加写入延迟
# 6.12 从节点加入可用性组
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
ALTER AVAILABILITY GROUP [AG1] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
"
2
3
从节点加入后,AG 的创建即完成。
预期输出
# 查看 AG 状态
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
SELECT
ag.name AS AG_Name,
replica_server_name,
role_desc,
synchronization_health_desc
FROM sys.availability_groups ag
JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id
JOIN sys.dm_hadr_availability_replica_states rs ON ar.replica_id = rs.replica_id
"
# 预期返回主从节点的角色(PRIMARY/SECONDARY)和同步健康状态(HEALTHY)
# 查看数据库同步状态
sqlcmd -S localhost -U SA -P '<Your_SA_Password>' -Q "
SELECT
database_name,
synchronization_state_desc,
is_suspended
FROM sys.dm_hadr_database_replica_states
"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 7. 与托管版本的选型对照
| 维度 | SQL Server on Linux(自建) | 托管实例(AWS RDS/Azure SQL) |
|---|---|---|
| 功能完整性 | 缺少 SSAS/SSRS/部分 Agent 子系统 | 完全功能(SSRS 需额外配置) |
| 运维复杂度 | 需自行管理备份、补丁、高可用 | 托管服务负责基础设施 |
| 权限级别 | 拥有 sysadmin(完全控制) | sysadmin 被封禁,边界见 RDS 运维边界文章 |
| 成本结构 | 许可证 + 基础设施(可自带许可) | 按资源使用量付费,许可证包含 |
| 适用场景 | 有专职 DBA、需完全控制、成本敏感 | 快速启动、无专职 DBA、希望 SLA 兜底 |
如果团队有专职 DBA 且需要 sysadmin 权限进行深度调优,自建是合理选择;如果希望「开箱即用」且能接受托管服务的权限边界,托管版本更省心。
# 8. 验证清单
安装完成后,逐项验证:
# 1. 服务状态
systemctl status mssql-server
# 2. 端口监听
ss -tlnp | grep 1433
# 3. 版本确认
sqlcmd -S localhost -U SA -P '<password>' -Q "SELECT @@VERSION"
# 4. 创建测试数据库
sqlcmd -S localhost -U SA -P '<password>' -Q "CREATE DATABASE [TestDB] COLLATE Chinese_PRC_CI_AS"
# 5. 中文数据测试
sqlcmd -S localhost -U SA -P '<password>' -Q "
USE TestDB;
CREATE TABLE t1 (id INT, name NVARCHAR(100));
INSERT INTO t1 VALUES (1, N'中文测试');
SELECT * FROM t1 WHERE name = N'中文测试';
"
# 6. 查看当前配置
sqlcmd -S localhost -U SA -P '<password>' -Q "
SELECT
SERVERPROPERTY('Collation') AS Collation,
(SELECT value FROM sys.configurations WHERE name = 'max server memory (MB)') AS MaxMemoryMB,
(SELECT value FROM sys.configurations WHERE name = 'max degree of parallelism') AS MAXDOP
"
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Agent 可直接解析的元数据块
{
"article_id": "sql-server-linux-setup",
"permalink": "/pages/sql-server-2019-always-on-deployment/",
"category": "数据库/其他数据库",
"tags": ["SQL Server", "Linux", "安装配置", "中文化"],
"commands": {
"install_repo": "curl -o /etc/yum.repos.d/mssql-server.repo https://packages.microsoft.com/config/rhel/7/mssql-server-2019.repo",
"install_sqlserver": "yum install -y mssql-server",
"setup_sqlserver": "/opt/mssql/bin/mssql-conf setup",
"check_status": "systemctl status mssql-server",
"set_datadir": "/opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /data/mssql/data",
"set_collation": "/opt/mssql/bin/mssql-conf set-collation Chinese_PRC_CI_AS",
"check_version": "sqlcmd -S localhost -U SA -P '<password>' -Q \"SELECT @@VERSION\"",
"check_collation": "sqlcmd -S localhost -U SA -P '<password>' -Q \"SELECT SERVERPROPERTY('Collation')\""
},
"config_keys": [
"filelocation.defaultdatadir",
"filelocation.defaultlogdir",
"filelocation.defaultbackupdir",
"network.tcpport",
"memory.memorylimitmb",
"maxdop",
"sqlagent.enabled"
],
"unsupported_features": [
"Merge Replication",
"CLR EXTERNAL_ACCESS/UNSAFE",
"Buffer Pool Extension",
"SQL Server Analysis Services",
"SQL Server Reporting Services(仅目录库可用)",
"SQL Server Agent CmdExec/PowerShell/Alerts"
],
"version_assertions": {
"based_on": "SQL Server 2019 (15.x)",
"supported_os": "RHEL 7.3+, CentOS 7.3+, Ubuntu 18.04/20.04/22.04, SLES 12 SP2+",
"source": "https://learn.microsoft.com/en-us/sql/linux/sql-server-linux-editions-and-components-2019"
},
"misconceptions": [
"Linux 版与 Windows 版功能完全一致(错,有若干不支持特性)",
"安装后就能直接用(错,需配置排序规则和目录权限)",
"可以随意修改排序规则(错,需重建系统数据库)",
"Agent 功能完整(错,缺少 PowerShell/CmdExec/Alerts)"
],
"risk_level": "low",
"related_articles": [
{
"title": "托管 SQL Server 的运维边界",
"permalink": "/pages/rds-sqlserver-managed-boundary/",
"relationship": "对照阅读:自建 vs 托管的权限差异"
}
]
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52