SqlServer 高可用
大约 15 分钟约 4488 字
SqlServer 高可用
高可用版本说明

更新每个主机的计算机名
vi /etc/hostname
#自行命名 db241.cluster 服务器主机的 hostname 必须少于等于 15 个字符,否则在配置过程会出现各种莫名其妙的权限报错
hostnamectl #查看命名主机名配置详解
# ====== 修改主机名 ======
# 方法 1:使用 hostnamectl(推荐)
hostnamectl set-hostname db241
# 方法 2:修改配置文件
vi /etc/hostname
# 写入:db241
# 生效(需要重新登录或执行)
bash # 重新加载 Shell 环境
# 验证主机名
hostnamectl
hostname
cat /etc/hostname
# ====== 重要注意事项 ======
# 1. 主机名必须 <= 15 个字符
# 2. 主机名中不能包含特殊字符(只用字母、数字、连字符)
# 3. 所有节点的主机名必须唯一
# 4. 修改主机名后需要重启 SQL Server
systemctl restart mssql-server更新 /etc/hosts
vi /etc/hosts
#内容
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
10.6.251.241 db241
10.6.251.242 db242/etc/hosts 配置详解
# ====== 完整的 /etc/hosts 配置 ======
cat > /etc/hosts << 'EOF'
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
# SQL Server AG 集群节点
10.6.251.241 db241
10.6.251.242 db242
# 可选:如果有第三个节点(见证服务器)
# 10.6.251.243 db243
EOF
# ====== 验证主机名解析 ======
# 在每个节点上测试
ping -c 3 db241
ping -c 3 db242
# 使用 getent 验证
getent hosts db241
getent hosts db242
# ====== DNS 配置(可选,如果使用 DNS 服务器) ======
# 如果使用内部 DNS,可以不配置 /etc/hosts
# 但建议同时配置 /etc/hosts 作为备用
# ====== 网络连通性测试 ======
# 测试所有节点之间的端口连通性
telnet db241 5022
telnet db242 5022
# 或使用 nc
nc -zv db241 5022
nc -zv db242 5022启用Always On
在托管 SQL Server 实例的每个节点上启用 Always On 可用性组,然后启动 mssql-server。 运行以下脚本:
/opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
systemctl restart mssql-serverAlways On 配置详解
# ====== 启用 HADR ======
# 在每个节点上执行
/opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
# 验证配置
/opt/mssql/bin/mssql-conf get hadr.hadrenabled
# 重启 SQL Server 使配置生效
systemctl restart mssql-server
# 验证服务状态
systemctl status mssql-server
# ====== 其他常用 mssql-conf 配置 ======
# 设置内存限制(建议不超过物理内存的 80%)
/opt/mssql/bin/mssql-conf set memory.memorylimitmb 4096
# 设置默认数据目录
/opt/mssql/bin/mssql-conf set filelocation.defaultdatadir /data/sqlserver/data
# 设置默认日志目录
/opt/mssql/bin/mssql-conf set filelocation.defaultlogdir /data/sqlserver/log
# 设置默认备份目录
/opt/mssql/bin/mssql-conf set filelocation.defaultbackupdir /backup/sqlserver
# 设置 TCP 端口
/opt/mssql/bin/mssql-conf set network.tcpport 1433
# 设置排序规则
/opt/mssql/bin/mssql-conf set sql.collation Chinese_PRC_CI_AS
# 查看所有配置
/opt/mssql/bin/mssql-conf dump启用 AlwaysOn_health 事件会话
可选择性地启用扩展事件 (XE),以便在对可用性组进行故障排除时帮助诊断根本原因。 在每个 SQL Server 实例上运行以下命令:
ALTER EVENT SESSION AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON);扩展事件与诊断
-- ====== 启用 AlwaysOn_health 扩展事件 ======
ALTER EVENT SESSION AlwaysOn_health ON SERVER WITH (STARTUP_STATE=ON);
-- 验证扩展事件是否启用
SELECT name, is_running
FROM sys.dm_xe_sessions
WHERE name = 'AlwaysOn_health';
-- ====== 查看可用性组状态 ======
SELECT
ag.name AS AG_name,
ag.state_desc AS AG_state,
replica_id,
group_database_id
FROM sys.availability_groups ag;
-- ====== 查看副本状态 ======
SELECT
ag.name AS AG_name,
ar.replica_server_name,
ar.state_desc AS replica_state,
ar.role_desc AS replica_role,
ar.operational_state_desc AS op_state,
ar.synchronization_health_desc AS sync_health,
ar.connected_state_desc AS connected_state
FROM sys.availability_groups ag
JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id;
-- ====== 查看数据库同步状态 ======
SELECT
ag.name AS AG_name,
db_name(dr.database_id) AS database_name,
dr.synchronization_state_desc AS sync_state,
dr.synchronization_health_desc AS sync_health,
dr.is_suspended,
dr.suspend_reason_desc
FROM sys.availability_groups ag
JOIN sys.availability_databases_cluster adc ON ag.group_id = adc.group_id
JOIN sys.dm_hadr_database_replica_states dr ON adc.group_database_id = dr.group_database_id;
-- ====== 查看最近错误日志 ======
EXEC sp_readerrorlog 0, 1, 'AlwaysOn';
EXEC sp_readerrorlog 0, 1, 'HADR';安装高可用性加载项(每个节点)
yum install subscription-manager
sudo subscription-manager register提示
- 1.先在此官网上注册账号:https://www.redhat.com/wapps/ugc/register.html
- 2.注册完后同意相关协议
- 3.常见错误
- 无法确认服务器身份:[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:618)
- vi /etc/rhsm/rhsm.conf #将insecure = 0改为insecure = 1保存
安装高可用性加载项详解
# ====== 方法 1:使用 Red Hat 订阅管理器 ======
# 安装 subscription-manager
yum install -y subscription-manager
# 注册系统(需要 Red Hat 账号)
sudo subscription-manager register
# 如果遇到 SSL 错误,修改配置
vi /etc/rhsm/rhsm.conf
# 将 insecure = 0 改为 insecure = 1
# 列出可用的订阅池
sudo subscription-manager list --available
# 附加高可用性订阅
sudo subscription-manager attach --pool=2c94b2c386e9fcae0186fca0707f5993
# 启用高可用性仓库
sudo subscription-manager repos --enable=rhel-ha-for-rhel-7-server-rpms
# 安装 Pacemaker
yum install -y pacemaker pcs fence-agents-all resource-agents
# ====== 方法 2:使用 CentOS/RHEL 直接安装 ======
# CentOS 7
yum install -y pacemaker pcs corosync fence-agents-all resource-agents
# CentOS 8 / RHEL 8
dnf install -y pacemaker pcs corosync fence-agents-all resource-agents
# ====== 验证安装 ======
rpm -qa | grep pacemaker
rpm -qa | grep pcs
rpm -qa | grep corosync
# 设置 hacluster 用户密码(每个节点)
echo "hacluster:HaClusterPass123!" | passwd --stdin hacluster
# 启动并启用 pcsd 服务
systemctl start pcsd
systemctl enable pcsd
systemctl status pcsd列出可用的注册池。(每个节点)
sudo subscription-manager list --available运行以下命令,将 RHEL 高可用性与订阅相关联(每个节点)
# 其中,"PoolId"是上一步中高可用性订阅的池 ID。
sudo subscription-manager attach --pool=2c94b2c386e9fcae0186fca0707f5993
#PoolId 2c94b2c386e9fcae0186fca0707f5993启用存储库 RHEL 7(每个节点)
sudo subscription-manager repos --enable=rhel-ha-for-rhel-7-server-rpms主节点创建证书
-- sunnyfancore@163.com 为自己定义的密码
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'sunnyfancore@163.com';
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm';
BACKUP CERTIFICATE dbm_certificate
TO FILE = '/var/opt/mssql/data/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/var/opt/mssql/data/dbm_certificate.pvk',
ENCRYPTION BY PASSWORD = 'sunnyfancore@163.com'
);
--如果需要删除
--DROP CERTIFICATE dbm_certificate
--DROP MASTER KEY证书配置详解
-- ====== 证书管理完整流程 ======
-- 在主节点上创建主密钥和证书
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'sunnyfancore@163.com';
-- 创建用于数据库镜像的证书
CREATE CERTIFICATE dbm_certificate WITH SUBJECT = 'dbm';
-- 验证证书是否创建成功
SELECT name, subject, start_date, expiry_date
FROM sys.certificates
WHERE name = 'dbm_certificate';
-- 备份证书和私钥
BACKUP CERTIFICATE dbm_certificate
TO FILE = '/var/opt/mssql/data/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/var/opt/mssql/data/dbm_certificate.pvk',
ENCRYPTION BY PASSWORD = 'sunnyfancore@163.com'
);
-- ====== 证书清理(如果需要重新配置) ======
DROP CERTIFICATE dbm_certificate;
DROP MASTER KEY;
-- ====== 查看已有证书 ======
SELECT * FROM sys.certificates;复制证书到从节点
cd /var/opt/mssql/data
scp dbm_certificate.* root@db242:/var/opt/mssql/data/复制证书到从节点详解
# ====== 复制证书文件 ======
cd /var/opt/mssql/data
# 复制到从节点
scp dbm_certificate.cer root@db242:/var/opt/mssql/data/
scp dbm_certificate.pvk root@db242:/var/opt/mssql/data/
# 如果有多个从节点
# scp dbm_certificate.* root@db243:/var/opt/mssql/data/
# ====== 验证文件传输 ======
# 在从节点上验证
ls -la /var/opt/mssql/data/dbm_certificate.*
# 应该看到 .cer 和 .pvk 两个文件
# ====== 设置正确的文件权限 ======
# 在从节点上执行
cd /var/opt/mssql/data
chown mssql:mssql dbm_certificate.cer
chown mssql:mssql dbm_certificate.pvk
chmod 600 dbm_certificate.pvk
chmod 644 dbm_certificate.cer
# ====== 安全传输(使用指定端口) ======
scp -P 22 /var/opt/mssql/data/dbm_certificate.cer root@db242:/var/opt/mssql/data/
scp -P 22 /var/opt/mssql/data/dbm_certificate.pvk root@db242:/var/opt/mssql/data/在每个目标服务器上,为 mssql 用户授予访问证书的权限。
cd /var/opt/mssql/data
chown mssql:mssql dbm_certificate.*还原从库的证书
-- sunnyfancore@163.com 为自己定义的密码
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'sunnyfancore@163.com';
CREATE CERTIFICATE dbm_certificate
FROM FILE = '/var/opt/mssql/data/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/var/opt/mssql/data/dbm_certificate.pvk',
DECRYPTION BY PASSWORD = 'sunnyfancore@163.com'
);还原证书详解
-- ====== 在从节点上还原证书 ======
-- 创建主密钥(使用与主节点相同的密码)
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'sunnyfancore@163.com';
-- 从文件还原证书
CREATE CERTIFICATE dbm_certificate
FROM FILE = '/var/opt/mssql/data/dbm_certificate.cer'
WITH PRIVATE KEY (
FILE = '/var/opt/mssql/data/dbm_certificate.pvk',
DECRYPTION BY PASSWORD = 'sunnyfancore@163.com'
);
-- 验证证书
SELECT name, subject, start_date, expiry_date
FROM sys.certificates
WHERE name = 'dbm_certificate';在所有服务器上创建数据库镜像终结点
-- 5022 为SQL Server AG 节点之间使用 TCP 通信,通过指定的端口传送消息
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;终结点配置详解
-- ====== 创建数据库镜像终结点 ======
-- LISTENER_PORT: AG 节点间通信端口(默认 5022)
-- ROLE: ALL 表示此端点可以作为所有角色
-- AUTHENTICATION: 使用证书认证
-- ENCRYPTION: REQUIRED ALGORITHM AES 表示必须加密通信
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;
-- ====== 验证终结点 ======
SELECT
name,
type_desc,
state_desc,
port
FROM sys.endpoints
WHERE type = 4; -- 4 = DATABASE_MIRRORING
-- 查看终结点连接
SELECT
ep.name,
ep.state_desc,
ec.connection_id,
ec.state_desc,
ec.connect_time,
ec.local_tcp_port,
ec.remote_tcp_port
FROM sys.endpoints ep
JOIN sys.dm_exec_connections ec ON ep.endpoint_id = ec.endpoint_id
WHERE ep.type = 4;
-- ====== 修改终结点端口(如果需要) ======
-- ALTER ENDPOINT Hadr_endpoint
-- FOR DATABASE_MIRRORING (LISTENER_PORT = 5023);打开 防火墙对 endpoint 对应的端口的支持
firewall-cmd --zone=public --add-port=5022/tcp --permanent
firewall-cmd --reload防火墙配置详解
# ====== 防火墙配置 ======
# SQL Server AG 需要开放的端口:
# 1433 - SQL Server 数据库引擎
# 5022 - AG 端点通信端口
# 2224 - Pacemaker 集群通信(如果使用 Pacemaker)
# 开放 SQL Server 端口
firewall-cmd --zone=public --add-port=1433/tcp --permanent
# 开放 AG 端点端口
firewall-cmd --zone=public --add-port=5022/tcp --permanent
# 如果使用 Pacemaker,开放集群端口
firewall-cmd --zone=public --add-port=2224/tcp --permanent
firewall-cmd --zone=public --add-port=3121/tcp --permanent
firewall-cmd --zone=public --add-port=5403/tcp --permanent
firewall-cmd --zone=public --add-port=5404/tcp --permanent
firewall-cmd --zone=public --add-port=5405/tcp --permanent
# 重新加载防火墙
firewall-cmd --reload
# 验证端口
firewall-cmd --list-ports
# ====== 验证端口连通性 ======
# 在主节点上测试
nc -zv db242 5022
nc -zv db242 1433
# 在从节点上测试
nc -zv db241 5022
nc -zv db241 1433
# ====== SELinux 配置 ======
# 如果启用了 SELinux,需要放行 SQL Server 和 Pacemaker
setsebool -P daemons_enable_cluster_mode on
# 检查 SELinux 状态
getenforce
# 查看 SQL Server 的 SELinux 上下文
ps -eZ | grep mssql创建可用性组
创建 AG。 设置 CLUSTER_TYPE = NONE。 此外,使用 FAILOVER_MODE = MANUAL 设置每个副本。 运行分析或报告工作负载的客户端应用程序可直接连接到辅助数据库。 还可以创建一个只读路由列表。 与主要副本的连接将读取连接请求循环转发到路由列表中的每个次要副本。
以下 Transact-SQL 脚本创建名为 sunnyfan_ag 的 AG。 脚本使用 SEEDING_MODE = AUTOMATIC 配置 AG 副本。 此设置会导致 SQL Server 在数据库添加到 AG 后自动在每个辅助服务器上创建数据库。 为环境更新以下脚本。 将 db241 和 db242 值替换为托管副本的 SQL Server 实例的名称。 使用为终结点设置的端口替换 <5022> 值。 在主 SQL Server 副本上运行以下 Transact-SQL 脚本:
CREATE AVAILABILITY GROUP [sunnyfan_ag]
WITH (CLUSTER_TYPE = NONE)
FOR REPLICA ON
N'db241' WITH (
ENDPOINT_URL = N'tcp://db241:5022',
AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
FAILOVER_MODE = MANUAL,
SEEDING_MODE = AUTOMATIC,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
),
N'db242' WITH (
ENDPOINT_URL = N'tcp://db242:5022',
AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT,
FAILOVER_MODE = MANUAL,
SEEDING_MODE = AUTOMATIC,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
);
ALTER AVAILABILITY GROUP [sunnyfan_ag] GRANT CREATE ANY DATABASE;提示
如果SERVERNAME为localhost,可能会出错,需修改成对应的服务器实例名,然后重启sqlserver 服务
SELECT @@SERVERNAME
EXEC sp_dropserver @@SERVERNAME
exec sp_addserver @server = 'db242',@local='LOCAL'
可用性组配置详解
-- ====== 可用性组参数说明 ======
-- CLUSTER_TYPE:
-- NONE - 无集群管理器(适合只读扩展)
-- WSFC - Windows Server 故障转移集群
-- EXTERNAL - 外部集群管理器(如 Pacemaker)
-- AVAILABILITY_MODE:
-- SYNCHRONOUS_COMMIT - 同步提交(零数据丢失,性能较低)
-- ASYNCHRONOUS_COMMIT - 异步提交(可能有数据丢失,性能较高)
-- FAILOVER_MODE:
-- AUTOMATIC - 自动故障转移(需要同步提交 + 集群)
-- MANUAL - 手动故障转移
-- SEEDING_MODE:
-- AUTOMATIC - 自动初始化从库(推荐)
-- MANUAL - 手动初始化从库
-- SECONDARY_ROLE:
-- ALLOW_CONNECTIONS = ALL - 允许所有连接(支持只读查询)
-- ALLOW_CONNECTIONS = READ_ONLY - 只允许只读连接
-- ====== 创建同步提交的 AG(高安全模式) ======
CREATE AVAILABILITY GROUP [sunnyfan_ag_sync]
WITH (CLUSTER_TYPE = NONE)
FOR REPLICA ON
N'db241' WITH (
ENDPOINT_URL = N'tcp://db241:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = MANUAL,
SEEDING_MODE = AUTOMATIC,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
),
N'db242' WITH (
ENDPOINT_URL = N'tcp://db242:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = MANUAL,
SEEDING_MODE = AUTOMATIC,
SECONDARY_ROLE (ALLOW_CONNECTIONS = ALL)
);
ALTER AVAILABILITY GROUP [sunnyfan_ag_sync] GRANT CREATE ANY DATABASE;
-- ====== 修改可用性组 ======
-- 将异步提交改为同步提交
ALTER AVAILABILITY GROUP [sunnyfan_ag]
MODIFY REPLICA ON N'db242' WITH (
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT
);
-- ====== 删除可用性组 ======
ALTER AVAILABILITY GROUP [sunnyfan_ag] REMOVE DATABASE [TestDB];
DROP AVAILABILITY GROUP [sunnyfan_ag];
-- ====== 只读路由配置 ======
-- 在主副本上配置只读路由
ALTER AVAILABILITY GROUP [sunnyfan_ag]
MODIFY REPLICA ON N'db241' WITH (
READ_ONLY_ROUTING_LIST = (N'db242')
);从副本执行加入
ALTER AVAILABILITY GROUP [sunnyfan_ag] Join WITH(cluster_type=NONE);
ALTER AVAILABILITY GROUP [sunnyfan_ag] Grant Create Any Database ;从节点加入详解
-- ====== 在从节点上执行 ======
-- 加入可用性组
ALTER AVAILABILITY GROUP [sunnyfan_ag] JOIN WITH (CLUSTER_TYPE = NONE);
-- 授予创建数据库权限
ALTER AVAILABILITY GROUP [sunnyfan_ag] GRANT CREATE ANY DATABASE;
-- 验证加入状态
SELECT
ag.name AS AG_name,
ar.replica_server_name,
ar.role_desc,
ar.operational_state_desc,
ar.synchronization_health_desc
FROM sys.availability_groups ag
JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id;
-- ====== 如果加入失败,排查步骤 ======
-- 1. 检查终结点是否启动
SELECT name, state_desc FROM sys.endpoints WHERE type = 4;
-- 2. 检查证书是否正确
SELECT name, subject FROM sys.certificates WHERE name = 'dbm_certificate';
-- 3. 检查网络连通性
-- 4. 检查 SQL Server 版本是否一致
SELECT @@VERSION;
-- 5. 检查 SQL Server 错误日志
EXEC sp_readerrorlog 0, 1, 'availability group';添加可用数据库到副本
-- 创建数据库视情况
create database [TestDB];
--修改数据库为完整备份
alter database [TestDB] set recovery full ;
--备份数据库
backup database [TestDB]
to disk = N'/var/opt/mssql/data/TestDB.bak';
--可用性组增加数据库
alter availability group [sunnyfan_ag]
add database [TestDB]添加数据库到 AG 详解
-- ====== 完整的数据库添加流程 ======
-- 1. 创建数据库
CREATE DATABASE [TestDB];
-- 2. 设置恢复模式为完整(必须)
ALTER DATABASE [TestDB] SET RECOVERY FULL;
-- 3. 执行完整备份(必须)
BACKUP DATABASE [TestDB]
TO DISK = N'/var/opt/mssql/data/TestDB.bak'
WITH FORMAT, INIT, NAME = N'TestDB-Full Backup';
-- 4. 执行日志备份(推荐)
BACKUP LOG [TestDB]
TO DISK = N'/var/opt/mssql/data/TestDB.trn'
WITH FORMAT, INIT, NAME = N'TestDB-Log Backup';
-- 5. 将数据库添加到可用性组
ALTER AVAILABILITY GROUP [sunnyfan_ag] ADD DATABASE [TestDB];
-- ====== 监控数据库同步状态 ======
-- 查看同步状态
SELECT
ag.name AS AG_name,
db_name(dr.database_id) AS database_name,
dr.replica_id,
dr.synchronization_state_desc AS sync_state,
dr.synchronization_health_desc AS health,
dr.is_suspended,
dr.log_send_queue_size,
dr.log_send_rate,
dr.redo_queue_size,
dr.redo_rate
FROM sys.availability_groups ag
JOIN sys.dm_hadr_database_replica_states dr ON ag.group_id = dr.group_id;
-- ====== 如果 SEEDING_MODE 为 MANUAL ======
-- 需要手动在从节点上还原数据库
-- 在从节点上执行:
RESTORE DATABASE [TestDB]
FROM DISK = N'/var/opt/mssql/data/TestDB.bak'
WITH NORECOVERY,
MOVE N'TestDB' TO N'/var/opt/mssql/data/TestDB.mdf',
MOVE N'TestDB_log' TO N'/var/opt/mssql/data/TestDB_log.ldf';
RESTORE LOG [TestDB]
FROM DISK = N'/var/opt/mssql/data/TestDB.trn'
WITH NORECOVERY;
-- 然后在主节点上执行:
ALTER AVAILABILITY GROUP [sunnyfan_ag] JOIN DATABASE [TestDB]
ON REPLICA ON N'db241' WITH (SEEDING_MODE = AUTOMATIC),
N'db242' WITH (SEEDING_MODE = AUTOMATIC);手动故障转移
-- ====== 手动故障转移(FAILOVER_MODE = MANUAL) ======
-- 在目标辅助副本上执行
ALTER AVAILABILITY GROUP [sunnyfan_ag] FAILOVER;
-- ====== 强制故障转移(数据可能丢失) ======
-- 仅在主副本不可达时使用
ALTER AVAILABILITY GROUP [sunnyfan_ag] FORCE_FAILOVER_ALLOW_DATA_LOSS;
-- ====== 验证故障转移结果 ======
SELECT
ag.name AS AG_name,
ar.replica_server_name,
ar.role_desc AS current_role
FROM sys.availability_groups ag
JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id
ORDER BY ar.role_desc;
-- ====== 将旧主节点重新加入 AG ======
-- 在旧主节点(现在是脱机状态)上执行
ALTER AVAILABILITY GROUP [sunnyfan_ag] JOIN WITH (CLUSTER_TYPE = NONE);排障指南
# ====== 常见问题排查 ======
# 1. 无法加入可用性组
# 检查终结点状态
sqlcmd -S db241 -U sa -P 'password' -Q "SELECT name, state_desc FROM sys.endpoints WHERE type = 4"
# 2. 证书认证失败
# 检查证书是否存在
sqlcmd -S db241 -U sa -P 'password' -Q "SELECT name FROM sys.certificates WHERE name = 'dbm_certificate'"
sqlcmd -S db242 -U sa -P 'password' -Q "SELECT name FROM sys.certificates WHERE name = 'dbm_certificate'"
# 3. 同步延迟过大
sqlcmd -S db241 -U sa -P 'password' -Q "
SELECT
db_name(dr.database_id) AS database_name,
dr.log_send_queue_size,
dr.log_send_rate,
dr.redo_queue_size,
dr.redo_rate
FROM sys.dm_hadr_database_replica_states dr
WHERE dr.is_local = 1
"
# 4. 查看详细错误日志
sqlcmd -S db241 -U sa -P 'password' -Q "EXEC sp_readerrorlog 0, 1, 'AlwaysOn'"
sqlcmd -S db241 -U sa -P 'password' -Q "EXEC sp_readerrorlog 0, 1, 'HADR'"
# 5. 网络问题
ss -tlnp | grep 5022
telnet db242 5022
# 6. SQL Server 服务状态
systemctl status mssql-server
journalctl -u mssql-server --since "1 hour ago"关键知识点
- 部署类主题的核心不是"装成功",而是"稳定运行、可排障、可回滚"。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
- 先把数据模型、访问模式和执行代价绑定起来理解。
- SQL Server AG 要求所有节点的 SQL Server 版本一致。
- 主机名必须 <= 15 个字符,且所有节点必须能互相解析。
- 数据库必须使用完整恢复模式(FULL)才能加入 AG。
- CLUSTER_TYPE = NONE 表示无外部集群管理器。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
- 保留执行计划、样本 SQL、索引定义和优化前后指标。
- 建立定期故障转移演练机制。
- 配置监控告警(同步延迟、副本状态、自动故障转移)。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
- 脱离真实数据分布设计索引。
- 主机名超过 15 个字符导致各种权限错误。
- 不配置 /etc/hosts 导致节点间无法通信。
- 数据库使用简单恢复模式导致无法加入 AG。
- 同步提交模式在高延迟网络中导致性能严重下降。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
- 继续深入存储引擎、复制机制、归档与冷热分层治理。
- 学习 Pacemaker + SQL Server AG 实现自动故障转移。
- 研究只读路由和负载均衡配置。
适用场景
- 当你准备把《SqlServer 高可用》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
落地建议
- 固定版本号与镜像标签,避免"latest"带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
- 建立 AG 状态监控和告警。
- 定期进行故障转移演练。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
- 使用 AlwaysOn_health 扩展事件辅助诊断。
- 检查终结点状态和证书配置。
复盘问题
- 如果把《SqlServer 高可用》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《SqlServer 高可用》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《SqlServer 高可用》最大的收益和代价分别是什么?
