从DNS配置到Pacemaker部署:一步步教你在Linux平台上实现AlwaysOn集群

从DNS配置到Pacemaker部署:一步步教你在Linux平台上实现AlwaysOn集群

AlwaysOn集群是SQL Server里唯一推荐的高可用性架构,

在AlwaysOn高可用性架构中,有非常多的高级功能,

  1. 可读辅助副本上的快照隔离级别会自动开启,这一机制旨在避免在数据库重做日志处理过程中发生阻塞,通过确保用户在辅助副本上能够执行数据的读取操作,从而避免因阻塞redo线程而影响数据的恢复效率。
  2. AlwaysOn技术还支持自动修复损坏的数据页,不论是主要副本还是任何辅助副本,一旦发现数据页损坏,系统会自动进行修复,确保数据的完整性和可用性。
  3. 跨平台仅读取缩放可用性组,支持Windows和Linux平台混合部署
  4. 要提交的所需已同步辅助副本,指定多少个辅助副本回应主要副本才能提交事务。

本篇文章带你如何在Linux平台搭建AlwaysOn集群,在Linux平台上增加了仅配置可用性模式等诸多功能,体验更加强大的AlwaysOn集群功能。

下面介绍基于Pacemaker集群的AlwaysOn可用性组部署的详细步骤, 集群各个节点的部署信息和域名信息如表1和表2所示, 为了方便起见,在集群搭建的过程中所有节点的防火墙服务都已经关闭,

表1:集群各个节点的信息如下:

节点名称 IP 用途 操作系统 数据库版本
DNS 192.168.22.112 DNS服务 CentOS 9.2
wwwmssql122 192.168.22.122 主要副本(同步提交) CentOS 9.2 SQL Server 2019
wwwmssql124 192.168.22.124 辅助副本(同步提交) CentOS 9.2 SQL Server 2019
wwwmssql128 192.168.22.128 辅助副本(同步提交) CentOS 9.2 SQL Server 2019
yahaha_listener 192.168.22.160 AlwaysOn侦听器

表2:各个节点的域名信息和可用性组信息如下:

节点名称 域名信息 IP
wwwmssql122 wwwmssql122.mssqlag.com 192.168.22.122
wwwmssql124 wwwmssql124.mssqlag.com 192.168.22.124
wwwmssql128 wwwmssql128.mssqlag.com 192.168.22.128
yahaha_listener yahaha_listener.mssqlag.com 192.168.22.160
yahaha_ag AlwaysOn可用性组名称

在Linux服务器上搭建AlwaysOn集群之前需要安装好所有需要用到的软件包,然后开启数据库实例的AlwaysOn功能,下面的代码会启用AlwaysOn可用性组功能并安装SQL Server高可用性支持包,然后安装Pacemaker相关的软件包,安装完Pacemaker软件包之后会自动创建一个系统账号hacluster,在每个数据库节点上执行以下命令:

yum clean all
yum makecache
yum config-manager --set-enabled highavailability
yum install -y pacemaker pcs fence-agents-all resource-agents corosync
yum install -y mssql-server-ha 

#打开AlwaysOn可用性组功能
/opt/mssql/bin/mssql-conf set hadr.hadrenabled 1
systemctl restart mssql-server

安装好上面的软件包之后,我们正式进入集群部署流程,下面开始部署DNS服务。

部署DNS服务

实际上可以不用搭建DNS服务,在每台机器节点上通过修改/etc/hosts文件添加机器名和IP地址的映射也能实现,但是实际生产环境还是建议搭建DNS服务,这样做更加正规。 部署DNS服务器实际上是注册节点wwwmssql122、wwwmssql124、wwwmssql128以及侦听器yahaha_listener到DNS服务,为AlwaysOn集群提供域名解析服务。

我们使用下面步骤进行搭建DNS服务,下面的所有操作都在192.168.22.112这台机器上执行:

  1. 安装BIND软件包和相关工具,执行下面命令:

    yum install -y bind
    yum install -y bind-utils

  2. 修改 /etc/named.conf文件,执行下面命令:

    sed -i.bak
    -e 's/listen-on port 53 { 127.0.0.1; }/listen-on port 53 { 192.168.22.112; }/'
    -e 's/allow-query { localhost; }/allow-query { any; }/'
    -e '/include "/etc/crypto-policies/back-ends/bind.config";/a\ check-names master warn;' /etc/named.conf

  3. 在/etc/named.rfc1912.zones文件的末尾追加文本,执行下面的命令:

    cat <<EOF >> /etc/named.rfc1912.zones

    #正向查找区域
    zone "mssqlag.com" IN {
    type master;
    file "mssqlag.com.zone";
    allow-update { none; };
    };

    #反向查找区域
    zone "22.168.192.in-addr.arpa" IN {
    type master;
    file "22.168.192.zone";
    allow-update { none; };
    };
    EOF

  4. 配置正向解析配置文件和反向解析配置文件,复制一份正向解析配置文件模板,复制出来的模版文件的文件名和第三步添加的【正向查找区域】名称一样。同理,对于反向向解析配置文件也是做同样的操作,执行下面的命令:

    cp -p /var/named/named.localhost /var/named/mssqlag.com.zone
    cp -p /var/named/named.loopback /var/named/22.168.192.zone
    #配置正向解析
    cat <<EOF > /var/named/mssqlag.com.zone
    $TTL 1D
    @ IN SOA mssqlag.com. admin.mssqlag.com. (
    2025011301 ; serial (日期+版本号)
    1D ; refresh
    1H ; retry
    1W ; expire
    3H ) ; minimum
    ;
    @ IN NS dns.mssqlag.com. ; 指定 DNS 服务器名称
    ;
    dns IN A 192.168.22.112 ; DNS 服务器 IP
    wwwmssql122 IN A 192.168.22.122 ; 数据库节点 IP
    wwwmssql124 IN A 192.168.22.124 ; 数据库节点 IP
    wwwmssql128 IN A 192.168.22.128 ; 数据库节点 IP
    yahaha_listener IN A 192.168.22.160 ; AlwaysOn 侦听器 IP
    EOF

    #配置反向解析
    cat <<EOF > /var/named/22.168.192.zone
    $TTL 1D
    @ IN SOA mssqlag.com. admin.mssqlag.com. (
    2025011301 ; serial
    1D ; refresh
    1H ; retry
    1W ; expire
    3H ) ; minimum
    ;
    @ IN NS dns.mssqlag.com. ; 指定 DNS 服务器名称
    ;
    112 IN PTR dns.mssqlag.com. ; 反向解析记录
    122 IN PTR wwwmssql122.mssqlag.com. ; 数据库节点反向解析
    124 IN PTR wwwmssql124.mssqlag.com. ; 数据库节点反向解析
    128 IN PTR wwwmssql128.mssqlag.com. ; 数据库节点反向解析
    160 IN PTR yahaha_listener.mssqlag.com. ; AlwaysOn 侦听器反向解析
    EOF

  5. 对各个配置文件进行语法检查,执行下面的命令:

    #检查配置文件语法
    named-checkconf /etc/named.conf
    named-checkconf /etc/named.rfc1912.zones
    #检查正向解析文件语法
    named-checkzone mssqlag.com /var/named/mssqlag.com.zone
    #检查反向解析文件语法
    named-checkzone 22.168.192.in-addr.arpa /var/named/22.168.192.zone

  6. 重启BIND服务,如果配置文件语法有问题,那么BIND服务会启动失败,执行下面的命令:

    systemctl enable named
    systemctl restart named

  7. 修改所有集群节点的网卡配置文件,把DNS解析指向DNS服务器,所有集群节点都要把网卡配置文件里的DNS1改为指向DNS服务器192.168.22.112然后重启机器,执行下面的命令:

DNS服务器节点修改如下

cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-ens160
TYPE=Ethernet
BOOTPROTO=static
NAME=ens160
DEVICE=ens160
ONBOOT=yes
IPADDR=192.168.22.112
PREFIX=24
GATEWAY=192.168.22.2
DNS1=192.168.22.112   #每台机器都改为DNS机器的ip
DNS2=114.114.114.114
DOMAIN=mssqlag.com   #搜索域名后缀
EOF

所有数据库节点修改如下

cat <<EOF > /etc/sysconfig/network-scripts/ifcfg-ens160
TYPE=Ethernet
BOOTPROTO=static
NAME=ens160
DEVICE=ens160
ONBOOT=yes
IPADDR=192.168.22.128
PREFIX=24
GATEWAY=192.168.22.2
DNS1=192.168.22.112   #每台机器都改为DNS机器的ip
DNS2=114.114.114.114
DOMAIN=mssqlag.com   ##搜索域名后缀
EOF

重启完机器之后,每个机器都要检查/etc/resolv.conf配置文件,如果看到search mssqlag.com和nameserver 192.168.22.112那么表示网卡配置文件无问题,执行下面的命令:

cat  /etc/resolv.conf
# Generated by NetworkManager
search mssqlag.com
nameserver 192.168.22.112
nameserver 114.114.114.114
  1. 测试DNS解析情况,在192.168.22.122机器上测试DNS解析,使用dig命令和ping命令测试正向解析和反向解析。解析结果里要重点关注ANSWER SECTION和SERVER这两个字段,SERVER的返回结果一定要是192.168.22.112#53(192.168.22.112) ,执行下面的命令:

    #测试正向解析,测试FQDN
    dig wwwmssql128.mssqlag.com
    #测试正向解析,测试短主机名
    dig wwwmssql128

    #测试反向解析
    dig -x 192.168.22.128

    #测试ping
    ping wwwmssql128
    ping wwwmssql128.mssqlag.com

至此,DNS服务就部署完毕,一定要确保第八步的测试都没有问题,否则会影响后续的集群搭建过程,下面正式开始部署AlwaysOn集群。

正式搭建AlwaysOn集群

创建AlwaysOn可用性组的步骤与Windows平台上的AlwaysOn可用性组创建方式基本一致。整个集群搭建过程实际上分为四大步骤,分别是:创建AlwaysOn集群、Pacemaker集群配置、Pacemaker资源配置和Pacemaker约束配置,下面是详细的搭建步骤:

  • 创建AlwaysOn集群
  1. 创建数据库主密钥和创建证书 ,根据提示在各个副本上执行,SQL代码如下:

    --主要副本wwwmssql122上执行
    USE master;
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'master@22222key123';
    CREATE CERTIFICATE HOST_22_122_cert WITH SUBJECT = 'HOST_22_122_certificate',START_DATE = '09/20/2010',EXPIRY_DATE = '01/01/2099';
    --辅助副本wwwmssql124上执行
    USE master;
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'master@22222key123';
    CREATE CERTIFICATE HOST_22_124_cert WITH SUBJECT = 'HOST_22_124_certificate',START_DATE = '09/20/2010',EXPIRY_DATE = '01/01/2099';
    --辅助副本wwwmssql128上执行
    USE master;
    CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'master@22222key123';
    CREATE CERTIFICATE HOST_22_128_cert WITH SUBJECT = 'HOST_22_128_certificate',START_DATE = '09/20/2010',EXPIRY_DATE = '01/01/2099';

  2. 创建镜像端点并添加证书,根据提示在各个副本上执行,SQL代码如下:

    --主要副本wwwmssql122上执行
    CREATE ENDPOINT Endpoint_Mirroring
    STATE = STARTED
    AS
    TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL )
    FOR
    DATABASE_MIRRORING
    ( AUTHENTICATION = CERTIFICATE HOST_22_122_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );
    --辅助副本wwwmssql124上执行
    CREATE ENDPOINT Endpoint_Mirroring
    STATE = STARTED
    AS
    TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL )
    FOR
    DATABASE_MIRRORING
    ( AUTHENTICATION = CERTIFICATE HOST_22_124_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );
    --辅助副本wwwmssql128上执行
    CREATE ENDPOINT Endpoint_Mirroring
    STATE = STARTED
    AS
    TCP ( LISTENER_PORT=5022 , LISTENER_IP = ALL )
    FOR
    DATABASE_MIRRORING
    ( AUTHENTICATION = CERTIFICATE HOST_22_128_cert , ENCRYPTION = REQUIRED ALGORITHM AES , ROLE = ALL );

  3. 每个数据库节点都备份证书然后互换,根据提示在各个副本上执行,SQL代码如下:

    --主要副本wwwmssql122上执行
    BACKUP CERTIFICATE HOST_22_122_cert TO FILE = '/data/mssql/1433/dbbackup/HOST_22_122_cert.cer';
    --辅助副本wwwmssql124上执行
    BACKUP CERTIFICATE HOST_22_124_cert TO FILE = '/data/mssql/1433/dbbackup/HOST_22_124_cert.cer';
    --辅助副本wwwmssql128上执行
    BACKUP CERTIFICATE HOST_22_128_cert TO FILE = '/data/mssql/1433/dbbackup/HOST_22_128_cert.cer';

  4. 证书互换并授权,将每个数据库节点上创建的证书传输(使用scp命令)给其他数据库节点,然后授予mssql操作系统帐户对其他节点证书的访问权限,根据提示在各个副本上执行,执行的命令如下:

    #主要副本wwwmssql122上执行
    scp /data/mssql/1433/dbbackup/HOST_22_122_cert.cer root@192.168.22.124:/data/mssql/1433/dbbackup/
    scp /data/mssql/1433/dbbackup/HOST_22_122_cert.cer root@192.168.22.128:/data/mssql/1433/dbbackup/
    chown -R mssql:mssql /data/mssql/1433/*
    #辅助副本wwwmssql124上执行
    scp /data/mssql/1433/dbbackup/HOST_22_124_cert.cer root@192.168.22.128:/data/mssql/1433/dbbackup/
    scp /data/mssql/1433/dbbackup/HOST_22_124_cert.cer root@192.168.22.122:/data/mssql/1433/dbbackup/
    chown -R mssql:mssql /data/mssql/1433/*
    #辅助副本wwwmssql128上执行
    scp /data/mssql/1433/dbbackup/HOST_22_128_cert.cer root@192.168.22.124:/data/mssql/1433/dbbackup/
    scp /data/mssql/1433/dbbackup/HOST_22_128_cert.cer root@192.168.22.122:/data/mssql/1433/dbbackup/
    chown -R mssql:mssql /data/mssql/1433/*

  5. 创建登录账号(供辅助副本使用),然后为登录账号创建数据库用户,再还原来自其他数据库节点的证书,最后授予登录账号对端点的CONNECT权限,根据提示在各个副本上执行,SQL代码如下:

    --主要副本wwwmssql122上执行
    CREATE LOGIN [wwwmssql124LoginUser] WITH PASSWORD = 'User_Pass@22222key123';
    CREATE USER [wwwmssql124User] FOR LOGIN [wwwmssql124LoginUser];
    CREATE CERTIFICATE HOST_22_124_cert AUTHORIZATION [wwwmssql124User] FROM FILE ='/data/mssql/1433/dbbackup/HOST_22_124_cert.cer';
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [wwwmssql124LoginUser];
    CREATE LOGIN [wwwmssql128LoginUser] WITH PASSWORD = 'User_Pass@22222key123';
    CREATE USER [wwwmssql128User] FOR LOGIN [wwwmssql128LoginUser];
    CREATE CERTIFICATE HOST_22_128_cert AUTHORIZATION [wwwmssql128User] FROM FILE ='/data/mssql/1433/dbbackup/HOST_22_128_cert.cer';
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [wwwmssql128LoginUser];
    --辅助副本wwwmssql124上执行
    CREATE LOGIN [wwwmssql122LoginUser] WITH PASSWORD = 'User_Pass@22222key123';
    CREATE USER [wwwmssql122User] FOR LOGIN [wwwmssql122LoginUser];
    CREATE CERTIFICATE HOST_22_122_cert AUTHORIZATION [wwwmssql122User] FROM FILE ='/data/mssql/1433/dbbackup/HOST_22_122_cert.cer';
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [wwwmssql122LoginUser];
    CREATE LOGIN [wwwmssql128LoginUser] WITH PASSWORD = 'User_Pass@22222key123';
    CREATE USER [wwwmssql128User] FOR LOGIN [wwwmssql128LoginUser];
    CREATE CERTIFICATE HOST_22_128_cert AUTHORIZATION [wwwmssql128User] FROM FILE ='/data/mssql/1433/dbbackup/HOST_22_128_cert.cer';
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [wwwmssql128LoginUser];
    --辅助副本wwwmssql128上执行
    CREATE LOGIN [wwwmssql122LoginUser] WITH PASSWORD = 'User_Pass@22222key123';
    CREATE USER [wwwmssql122User] FOR LOGIN [wwwmssql122LoginUser];
    CREATE CERTIFICATE HOST_22_122_cert AUTHORIZATION [wwwmssql122User] FROM FILE ='/data/mssql/1433/dbbackup/HOST_22_122_cert.cer';
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [wwwmssql122LoginUser];
    CREATE LOGIN [wwwmssql124LoginUser] WITH PASSWORD = 'User_Pass@22222key123';
    CREATE USER [wwwmssql124User] FOR LOGIN [wwwmssql124LoginUser];
    CREATE CERTIFICATE HOST_22_124_cert AUTHORIZATION [wwwmssql124User] FROM FILE ='/data/mssql/1433/dbbackup/HOST_22_124_cert.cer';
    GRANT CONNECT ON ENDPOINT::Endpoint_Mirroring TO [wwwmssql124LoginUser];

  6. 启动镜像端点和创建AlwaysOn集群健康检测相关的扩展事件,根据提示在各个副本上执行,SQL代码如下:

    --启动镜像端点和创建AlwaysOn集群健康检测的扩展事件
    --主要副本wwwmssql122(192.168.22.122)上执行
    USE master
    GO
    IF (SELECT state FROM sys.endpoints WHERE name = N'Endpoint_Mirroring') <> 0
    BEGIN
    ALTER ENDPOINT [Endpoint_Mirroring] STATE = STARTED
    END
    GO
    IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
    BEGIN
    ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
    END
    IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
    BEGIN
    ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
    END
    GO
    --辅助副本wwwmssql124上执行(192.168.22.124)上执行
    USE master
    GO
    IF (SELECT state FROM sys.endpoints WHERE name = N'Endpoint_Mirroring') <> 0
    BEGIN
    ALTER ENDPOINT [Endpoint_Mirroring] STATE = STARTED
    END
    GO
    IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
    BEGIN
    ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
    END
    IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
    BEGIN
    ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
    END
    GO
    --辅助副本wwwmssql128上执行(192.168.22.128)上执行
    USE master
    GO
    IF (SELECT state FROM sys.endpoints WHERE name = N'Endpoint_Mirroring') <> 0
    BEGIN
    ALTER ENDPOINT [Endpoint_Mirroring] STATE = STARTED
    END
    GO
    IF EXISTS(SELECT * FROM sys.server_event_sessions WHERE name='AlwaysOn_health')
    BEGIN
    ALTER EVENT SESSION [AlwaysOn_health] ON SERVER WITH (STARTUP_STATE=ON);
    END
    IF NOT EXISTS(SELECT * FROM sys.dm_xe_sessions WHERE name='AlwaysOn_health')
    BEGIN
    ALTER EVENT SESSION [AlwaysOn_health] ON SERVER STATE=START;
    END
    GO

  7. 正式创建AlwaysOn可用性组和侦听器,把【TestDB】这个用户数据库加入到可用性组,一定要确保【TestDB】数据库已经做过完整备份以满足先决条件,端点URL在这里需要手动填写,如果想自动填写只能使用SSMS管理器自带的AlwaysOn可用性组创建向导界面,它会自动填写端点URL,由于使用的是【自动种子】这种数据初始化方式,非常方便的不需要备份还原到其他辅助副本,EXTERNAL群集类型是可用性组托管在外部群集技术(例如Pacemaker)管理的数据库实例上时使用以实现高可用性和灾难恢复。数据库级别运行状况检测(DB_FAILOVER)将为可用性组启用数据库级别运行状况检测,通俗的讲,此选项会让可用性组的运行状况检测不只在数据库实例层面进行,而转为针对数据库进行检测,当检测到数据库不再处于联机状态以及其它问题时将触发可用性组的自动故障转移,下面代码只需要在数据库节点wwwmssql122上执行,SQL代码如下:

    --正式创建AlwaysOn可用性组和侦听器
    --主要副本wwwmssql122(192.168.22.122)上执行
    USE [master]
    GO
    CREATE AVAILABILITY GROUP [yahaha_ag]
    WITH (AUTOMATED_BACKUP_PREFERENCE = SECONDARY,
    DB_FAILOVER = ON,
    DTC_SUPPORT = NONE,
    CLUSTER_TYPE = EXTERNAL,
    REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0)
    FOR DATABASE [TestDB]
    REPLICA ON N'wwwmssql122' WITH (ENDPOINT_URL = N'TCP://wwwmssql122.mssqlag.com:5022', FAILOVER_MODE = EXTERNAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = (N'wwwmssql124',N'wwwmssql128')), SECONDARY_ROLE(READ_ONLY_ROUTING_URL = N'TCP://wwwmssql122.mssqlag.com:1433', ALLOW_CONNECTIONS = ALL)),
    N'wwwmssql124' WITH (ENDPOINT_URL = N'TCP://wwwmssql124.mssqlag.com:5022', FAILOVER_MODE = EXTERNAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = (N'wwwmssql122',N'wwwmssql128')), SECONDARY_ROLE(READ_ONLY_ROUTING_URL = N'TCP://wwwmssql124.mssqlag.com:1433', ALLOW_CONNECTIONS = ALL)),
    N'wwwmssql128' WITH (ENDPOINT_URL = N'TCP://wwwmssql128.mssqlag.com:5022', FAILOVER_MODE = EXTERNAL, AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, BACKUP_PRIORITY = 50, SEEDING_MODE = AUTOMATIC, PRIMARY_ROLE(READ_ONLY_ROUTING_LIST = (N'wwwmssql122',N'wwwmssql124')), SECONDARY_ROLE(READ_ONLY_ROUTING_URL = N'TCP://wwwmssql128.mssqlag.com:1433', ALLOW_CONNECTIONS = ALL));
    GO
    --创建AlwaysOn侦听器
    ALTER AVAILABILITY GROUP [yahaha_ag]
    ADD LISTENER N'yahaha_listener' (
    WITH IP
    ((N'192.168.22.160', N'255.255.255.0')
    )
    , PORT=1433);
    GO

  8. 联接另外两个辅助副本,根据提示在另外两个辅助副本上执行,SQL代码如下:

    --联接各个辅助副本
    --辅助副本wwwmssql124上执行(192.168.22.124)上执行
    USE master
    GO
    ALTER AVAILABILITY GROUP [yahaha_ag] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
    GO
    ALTER AVAILABILITY GROUP [yahaha_ag] GRANT CREATE ANY DATABASE;
    GO
    --辅助副本wwwmssql128上执行(192.168.22.128)上执行
    USE master
    GO
    ALTER AVAILABILITY GROUP [yahaha_ag] JOIN WITH (CLUSTER_TYPE = EXTERNAL);
    GO
    ALTER AVAILABILITY GROUP [yahaha_ag] GRANT CREATE ANY DATABASE;
    GO

  9. 为Pacemaker创建数据库登录名,这里设置密码为Qwezxc123!,实际生产环境需要设置更为复杂的密码, Pacemaker将通过该【数据库登录名】连接到数据库实例以执行自动故障转移,所以需要对该登录名授予足够的管理权限,在所有副本上执行,SQL代码如下:

    USE master
    GO
    --为pacemaker创建登录名
    CREATE LOGIN PacemakerLogin WITH PASSWORD = 'QweUUU123!';
    --对登录名给予sysadmin服务器角色权限
    ALTER SERVER ROLE sysadmin ADD MEMBER [PacemakerLogin]
    GO

从图看到AlwaysOn集群已经搭建出来,各个数据库节点、侦听器和数据库都已经开始同步。

  • Pacemaker集群配置
  1. 配置Pacemaker、Corosync和pcs开机自动启动,然后动pcs服务,在所有数据库节点上执行以下命令:

    systemctl enable pacemaker
    systemctl enable corosync
    systemctl enable pcsd
    systemctl start pcsd

  2. 为了方便起见,笔者在集群搭建的过程中所有节点的防火墙服务都已经关闭,但是在生产环境中需要设置防火墙服务,开放防火墙规则以允许Pacemaker通信,需要确保以下端口允许通信:

    TCP端口2224用于PCS和节点间通信
    TCP端口3121和21064用于Pacemaker Remote和不同的组件通信。
    UDP端口5405用于各个节点之间Corosync的通信

  3. 设置Pacemaker集群的账号密码,给Pacemaker附带的系统账号hacluster设置密码(密码为QweUUU123!,仅供示例),hacluster账号作为每个节点的集群账号,在所有数据库节点上执行以下命令:

    passwd hacluster

  4. 配置集群节点认证,使用刚才的集群帐户来配置集群节点之间的身份验证,pcs host auth命令的作用是通过指定的用户名和密码(在这里是hacluster用户)配置集群节点之间的信任关系。这里输入上一步的用户名(hacluster)和密码(QweUUU123!),在任意一个数据库节点执行以下命令:

    pcs host auth wwwmssql122 wwwmssql124 wwwmssql128 -u hacluster -p 'QweUUU123!'

  5. 创建Pacemaker集群并启动,最后设置集群开机自启动,pcs cluster setup命令的作用是初始化一个新的Pacemaker集群,其中yahahacluster是新集群的名称,该集群包含三个节点wwmssql122、wwwmssql124和wwwmssql128。在任意一个数据库节点执行以下命令:

    pcs cluster setup yahahacluster wwwmssql122 wwwmssql124 wwwmssql128
    pcs cluster start --all
    pcs cluster enable --all

  6. 在/var/opt/mssql/secrets/目录下创建名为passwd的文件,并将数据库Pacemaker登录用户的凭据写入passwd文件,以便Pacemaker能连接数据库执行自动故障转移,在所有数据库节点上执行以下命令:

    cat > /var/opt/mssql/secrets/passwd << EOF
    PacemakerLogin
    QweUUU123!
    EOF

  7. 设置对passwd文件只允许文件所有者读取,其他用户无法读取和修改,在所有数据库节点上执行以下命令:

    chmod 400 /var/opt/mssql/secrets/passwd

  8. 禁用配置隔离 在任意一个数据库节点执行以下命令:

    pcs property set stonith-enabled=false

  9. 启用集群故障恢复机制 在任意一个数据库节点执行以下命令:

    pcs property set start-failure-is-fatal=false

  • Pacemaker资源配置
  1. 在Pacemaker中创建AlwaysOn可用性组资源 yahaha_ag_linux是资源名称用于标识一个AlwaysOn可用性组资源。ocf:mssql:ag的意思是使用OCF(Open Cluster Framework)标准里的【mssql】资源代理集合里的【ag】资源代理来管理AlwaysOn可用性组。在任意一个数据库节点执行以下命令:

    pcs resource create yahaha_ag_linux ocf:mssql:ag ag_name=yahaha_ag meta failure-timeout=60s promotable notify=true

  2. 在Pacemaker中创建侦听器资源 agvip是资源名称用于标识AlwaysOn侦听器的虚拟IP资源。ocf:heartbeat:IPaddr2的意思是使用【heartbeat】资源代理集合里的【IPaddr2】资源代理用于管理虚拟IP地址。在任意一个数据库节点执行以下命令:

    pcs resource create ag_vip_linux ocf:heartbeat:IPaddr2 ip=192.168.22.160

  • Pacemaker约束配置
  1. 添加协同位置约束(Colocation Constraint) 资源的协同位置约束确保虚拟IP资源(ag_vip_linux)与AlwaysOn可用性组资源的主节点(Promoted Master)运行在同一节点上。在任意一个数据库节点执行以下命令:

    pcs constraint colocation add ag_vip_linux with Promoted yahaha_ag_linux-clone INFINITY with-rsc-role=Master

  2. 添加排序约束(Ordering Constraint) 协同位置约束有一个隐式排序约束,在对故障节点进行故障转移之后也需要转移虚拟IP资源。在任意一个数据库节点执行以下命令:

    pcs constraint order promote yahaha_ag_linux-clone then start ag_vip_linux

至此,整个集群已经搭建完毕,现在需要检查Pacemaker集群和AlwaysOn集群的状态,在任意一个数据库节点执行以下命令:

#检查集群的状态
pcs status --full 
#检查集群资源的情况
pcs resource

从pcs resource命令结果和pcs status --full命令结果可以看到,当前Pacemaker集群的仲裁状态正常,当前集群主角色在wwwmssql122机器上运行,侦听器资源绑定在wwwmssql122机器上并且是启动状态。 pcs status --full命令的结果如下:

Cluster name: yahahacluster
Cluster Summary:
  * Stack: corosync (Pacemaker is running)
  * Current DC: wwwmssql122 (1) (version 2.1.9-1.el9-49aab9983) - partition with quorum
  * Last updated: Fri Jan 17 18:48:38 2025 on wwwmssql122
  * Last change:  Thu Jan 16 22:57:32 2025 by root via root on wwwmssql122
  * 3 nodes configured
  * 4 resource instances configured
Node List:
  * Node wwwmssql122 (1): online, feature set 3.19.6
  * Node wwwmssql124 (2): online, feature set 3.19.6
  * Node wwwmssql128 (3): online, feature set 3.19.6
Full List of Resources:
  * Clone Set: yahaha_ag_linux-clone [yahaha_ag_linux] (promotable):
    * yahaha_ag_linux (ocf:mssql:ag):  Promoted wwwmssql122
    * yahaha_ag_linux (ocf:mssql:ag):  Unpromoted wwwmssql124
    * yahaha_ag_linux (ocf:mssql:ag):  Unpromoted wwwmssql128
  * ag_vip_linux (ocf:heartbeat:IPaddr2):  Started wwwmssql122
Node Attributes:
  * Node: wwwmssql122 (1):
    * master-yahaha_ag_linux           : 20        #节点拥有的分数
  * Node: wwwmssql124 (2):
    * master-yahaha_ag_linux           : 10        #节点拥有的分数
  * Node: wwwmssql128 (3):
    * master-yahaha_ag_linux           : 10        #节点拥有的分数
Migration Summary:
Tickets:
PCSD Status:
  wwwmssql122: Online
  wwwmssql124: Online
  wwwmssql128: Online
Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled

pcs resource命令的结果如下:

  * Clone Set: yahaha_ag_linux-clone [yahaha_ag_linux] (promotable):
    * Promoted: [ wwwmssql122 ]
    * Unpromoted: [ wwwmssql124 wwwmssql128 ]
  * ag_vip_linux (ocf:heartbeat:IPaddr2):  Started wwwmssql122

在SSMS中打开AlwaysOn集群控制面板,从图看到查看当前AlwaysOn集群的状态是【正常运行】,并且主要副本是在wwwmssql122机器上运行,说明集群搭建没有任何问题。

从图看到,我们使用侦听器IP【192.168.22.160】连接数据库然后查询和更新数据是完全没有问题的, 从【select SERVERPROPERTY('ServerName')】语句的执行结果看到当前连接的是主要副本【wwwmssql122】, 使用侦听器IP连接数据库的速度也非常快。

集群故障转移测试

使用Pacemaker的AlwaysOn集群无法使用TSQL语句或者SSMS界面菜单对可用性组资源进行数据库故障转移。 AlwaysOn集群的一部分管理操作只能使用pcs命令来完成,下面演示使用pcs命令手动对数据库进行故障转移:

  • 数据库手动故障转移测试

接下来演示手动将资源yahaha_ag_linux从当前运行的节点(wwwmssql122)转移到wwwmssql124节点,使用pcs命令进行手动故障切换要比SSMS的界面菜单先进,因为使用SSMS的界面菜单进行手动故障切换无法选择切换目标,但是pcs命令可以选择切换目标,这里选择的切换目标是wwwmssql124节点,只需要在任意一个数据库节点执行以下命令:

pcs resource move yahaha_ag_linux-clone wwwmssql124

从图看到,主要副本已经自动转移到wwwmssql124节点,使用侦听器IP也能自动连接到新的主要副本,从【select SERVERPROPERTY('ServerName')】语句的执行结果看到当前的主要副本已经是wwwmssql124节点。

集群的控制台面板如下

侦听器连接到最新的主要副本如下

执行pcs resource命令查看当前的资源情况,pcs resource命令的结果如下:

pcs resource
  * Clone Set: yahaha_ag_linux-clone [yahaha_ag_linux] (promotable):
    * Promoted: [ wwwmssql124 ]
    * Unpromoted: [ wwwmssql122 wwwmssql128 ]
  * ag_vip_linux (ocf:heartbeat:IPaddr2):  Started wwwmssql124

从命令的结果看到主角色已经转移到wwwmssql124节点,AlwaysOn侦听器资源也已经绑定到wwwmssql124节点。

  • 数据库自动故障转移测试

接下来演示强制将wwwmssql124节点关机,以便查看自动故障转移的情况,这里需要注意的是,自动故障转移也是只能转移到【同步提交模式的辅助副本】,在【wwwmssql124】节点上执行以下命令:

poweroff

从图看到,主要副本已经自动转移到wwwmssql122节点,使用侦听器IP也能自动连接到新的主要副本,从【select SERVERPROPERTY('ServerName')】语句的执行结果看到当前的主要副本已经是wwwmssql122节点,自动故障转移是非常成功的。

集群的控制台面板如下

侦听器连接到最新的主要副本如下

执行pcs resource命令查看当前的资源情况,pcs resource命令的结果如下:

pcs resource
  * Clone Set: yahaha_ag_linux-clone [yahaha_ag_linux] (promotable):
    * Promoted: [ wwwmssql122 ]
    * Unpromoted: [ wwwmssql128 ]
    * Stopped: [ wwwmssql124 ]
  * ag_vip_linux (ocf:heartbeat:IPaddr2):  Started wwwmssql122

从命令的结果看到主角色已经转移到wwwmssql122节点,AlwaysOn侦听器资源也已经绑定到wwwmssql122节点,wwwmssql124节点已经不可用。从当前的测试结果来看,无论是【手动故障转移】还是【自动故障转移】都非常顺利和丝滑,跟在Windows平台上的数据库故障转移体验是完全一样的。

总结

本文介绍了在Linux环境下为SQL Server数据库的AlwaysOn集群的搭建,借助Pacemaker集群的强大能力为数据库高可用保驾护航。另外,Linux环境下的AlwaysOn集群除了Pacemaker之外还可以使用其他的集群技术,

底层的故障转移原理都是一样的。

本文版权归作者所有,未经作者同意不得转载。