接着上篇将, Availability Group 在 Linux 上的搭建。
这篇的主要目的是讲解高可用实现基础,故障时效自动转移。
上篇原文点这里
8. Pacemaker 的安装
在配置完毕 AG 的时候,一定要配置 Pacemaker.
以下六个步骤除了 pcs 第5步,其他都需要在集群中的每台节点上运行。
详细构建与解说可以查看【参考文章】。
1. 大致需要安装 2个软件和 1 个工具:
- Pacemaker
- Corosync
- Pcsd
默认情况下,这三个软件都在自带的 repository 库中配置好了,只要执行安装即可:
代码语言:javascript复制yum install -y pacemaker,corosync,pcs
pcsd 是 pacemaker 的客户端命令执行程序,任何的功能都需要 pcsd 来启动和设置,pacemaker 是服务程序。当 pcsd, pacemaker 都配置好之后,使用命令 pcs 就可以用来和 pacemaker 交互了。所以 pcs 才是真正执行集群管理的程序软件,只要在其中一台节点上运行 pcs, 命令即将被送到各个节点去运行。
从安装的日志分析, corosync 会在安装 pacemaker 的时候一起安装,因此不需要特别去单独安装。pcs 是需要独立安装的。
MSDN 文档中规定,还需要安装额外的两个程序:
代码语言:javascript复制yum install -y fence-agents-all resource-agents
但 fency-agents-all 没有找到安装包,而 resource-agents 却已经安装完毕了。
2. 开启防火墙端口
代码语言:javascript复制firewall-cmd --permanent --add-service=high-availability
firewall-cmd --reload
如果没有 high availability 的配置,也可以指定端口:
TCP:ports 2224,3121,21064 UDP:port 5405
3. 设置用户密码
这个用户非常重要,他是创建集群的账户,有了他的存在,集群才能运行起来,和 sql server 安装用户要区分开来,实际上这两个用户需要分开建。
代码语言:javascript复制passwd hacluster
为了方便这里的用户密码和 sa 密码一致!
- 开启集群的重启回线设置
当节点失效了,修复后需要重新回到集群,这叫做回线。此功能需要设置:
代码语言:javascript复制systemctl enable pcsd
systemctl start pcsd
systemctl enable pacemaker
5. 建立集群
代码语言:javascript复制pcs cluster auth centos00 centos01 centos02 -u hacluster -p l****n****6.
pcs cluster setup --name crmcluster centos00 centos1 centos02
pcs cluster start --all
pcs cluster enable --all
配置授权的程序运行过长,而且中间经常有错误,比如失联,timeout等。尝试着多联几遍,发现效果并不理想,始终有一台机器失联。
所以尝试着想单台计算机节点去授权:
代码语言:javascript复制[huangyun@centos00 ~]$ pcs cluster auth centos00
Username: hacluster
Password:
Please authenticate yourself to the local pcsd
Username: huangyun
Password:
Port (default: 2224):
Error: Access denied
换成 root.
###### 小结下集群的主要步骤:
pcs 的程序只要在其中一台运行即可
5.1 开启 pcs 程序:
代码语言:javascript复制systemctl enable pcsd
systemctl start pcsd
systemctl enable pacemaker
** 每台节点都需要执行
5.2 授权节点
代码语言:javascript复制pcs cluster auth centos00 centos01 centos02 -u hacluster -p l****n****6.
更建议换成:
代码语言:javascript复制pcs cluster auth centos00 centos01 centos02
5.3 设置集群属性: 集群名,节点名
代码语言:javascript复制pcs cluster setup --name crmcluster centos00 centos1 centos02
代码语言:javascript复制[root@centos00 huangyun]# pcs cluster setup --name crmcluster centos00 centos01 centos02
Destroying cluster on nodes: centos00, centos01, centos02...
centos02: Stopping Cluster (pacemaker)...
centos01: Stopping Cluster (pacemaker)...
centos00: Stopping Cluster (pacemaker)...
centos01: Successfully destroyed cluster
centos02: Successfully destroyed cluster
centos00: Successfully destroyed cluster
Sending 'pacemaker_remote authkey' to 'centos00', 'centos01', 'centos02'
centos00: successful distribution of the file 'pacemaker_remote authkey'
centos02: successful distribution of the file 'pacemaker_remote authkey'
centos01: successful distribution of the file 'pacemaker_remote authkey'
Sending cluster config files to the nodes...
centos00: Succeeded
centos01: Succeeded
centos02: Succeeded
Synchronizing pcsd certificates on nodes centos00, centos01, centos02...
centos00: Success
centos01: Success
centos02: Success
Restarting pcsd on the nodes in order to reload the certificates...
centos02: Success
centos00: Success
centos01: Success
5.4 开启集群服务
代码语言:javascript复制pcs cluster start
pcs cluster enable
6 安装 sql server resource agent
代码语言:javascript复制yum install mssql-server-ha
7. 配置 fencing(STONITH)
fencing 的作用是让失效的节点回线,一旦节点故障离线了,fencing 会引导节点重新回到集群。
STONITH: shoot the other node in the head
常规情况,fencing 特性是必须要在集群的节点中启动的。但如果处于测试的目的,可以不启动。可以尝试着去启动它,对于以后部署圣餐环境,是有好处的,相当于一次生产环境中部署的演练。在本文中为了方便快捷的部署,先将其关闭。
fencing 可以从两方面进行集群资源的控制,一是节点本身,二是节点上提供的资源,比如硬盘,SQL 服务等。
针对节点本身一级的控制:
代码语言:javascript复制pcs property set stonith-enabled=false
问题: 1 集群管理器(Cluster Manager)为什么不能集成 fencing 的功能? 2 集群资源与集群管理器之间的互动,依靠什么来接口? 3 fencing 的实现
8 集群“心跳”的设置
“心跳”(Heart Beat)的概念,在这里是指集群节点之间互相通信,检查健康状态和集群属性变更的机制。通过设置集群属性 cluster-recheck-interval 来确定“心跳” 的时间间隔。
一旦集群中的某一个节点下线(不能互相通信),集群管理器可以尝试着在一段时间(failure-timeout)后去重启这台节点。如果在这段时间内节点又有反应(能与集群互相通信)了,那么在接收到这个回线的信号之后,就取消重启先前标记为下线的节点。
代码语言:javascript复制pcs property set cluster-recheck-interval=2min
不建议把 cluster-recheck-interval 设置的过短,比如 60s; 一般 failure-timeout 可以设置的短一些,60s, 而 cluster-recheck-interval 要设置的比 failure-timeout 长一些。
代码语言:javascript复制pcs resource update [crmag] meta failure-timeout=60s
9 为 Pacemaker 设置 SQL Server Login 账户
代码语言:javascript复制use master
go
CREATE LOGIN PaceMaker WITH PASSWORD='PMLoginPass123.'
ALTER SERVER ROLE sysadmin ADD MEMBER PaceMaker
GO
在每一台集群实例上都执行上面的命令。
代码语言:javascript复制[root@centos00 secrets]# cat login.bat
echo 'PaceMaker' >> ~/pacemaker-passwd
echo 'PMLoginPass123.' >> ~/pacemaker-passwd
mv ~/pacemaker-passwd /var/opt/mssql/secrets/passwd
chown root:root /var/opt/mssql/secrets/passwd
chmod 400 /var/opt/mssql/secrets/passwd
在每一台集群节点上执行上述脚本
10 创建 AG (Availability Groups)集群资源
代码语言:javascript复制pcs resource create crmag_cluster ocf:mssql:ag ag_name=crmag meta failure-timeout=30s master notify=true
11 创建虚拟 IP 地址
代码语言:javascript复制pcs resource create virtualip ocf:heartbeat:IPaddr2 ip=192.168.1.15
与我们的 SQL Server 实例所在节点的网段一致。
12 Add colocation constraint
代码语言:javascript复制pcs constraint colocation add virtualip crmag_cluster-master INFINITY with-rsc-role=master
INFINITY 一定是大写,但还是会遇到以下错误:
代码语言:javascript复制Error: Unable to update cib
Call cib_replace failed (-203): Update does not conform to the configured schema
<cib crm_feature_set="3.0.14" validate-with="pacemaker-2.10" epoch="10" num_updates="0" admin_epoch="0" cib-last-written="Tue Aug 21 23:16:35 2018" update-origin="centos00" update-client="cibadmin" update-user="root" have-quorum="0" dc-uuid="1">
<configuration>
<crm_config>
<cluster_property_set id="cib-bootstrap-options">
<nvpair id="cib-bootstrap-options-have-watchdog" name="have-watchdog" value="false"/>
<nvpair id="cib-bootstrap-options-dc-version" name="dc-version" value="1.1.18-11.el7_5.3-2b07d5c5a9"/>
<nvpair id="cib-bootstrap-options-cluster-infrastructure" name="cluster-infrastructure" value="corosync"/>
<nvpair id="cib-bootstrap-options-cluster-name" name="cluster-name" value="crmcluster"/>
<nvpair id="cib-bootstrap-options-stonith-enabled" name="stonith-enabled" value="false"/>
<nvpair id="cib-bootstrap-options-cluster-recheck-interval" name="cluster-recheck-interval" value="2min"/>
</cluster_property_set>
</crm_config>
<nodes>
<node id="1" uname="centos00"/>
<node id="2" uname="centos01"/>
<node id="3" uname="centos02"/>
</nodes>
<resources>
<master id="crmag_cluster-master">
<primitive class="ocf" id="crmag_cluster" provider="mssql" type="ag">
<instance_attributes id="crmag_cluster-instance_attributes">
<nvpair id="crmag_cluster-instance_attributes-ag_name" name="ag_name" value="crmag"/>
</instance_attributes>
<meta_attributes id="crmag_cluster-meta_attributes">
<nvpair id="crmag_cluster-meta_attributes-failure-timeout" name="failure-timeout" value="30s"/>
</meta_attributes>
<operations>
<op id="crmag_cluster-demote-interval-0s" interval="0s" name="demote" timeout="10"/>
<op id="crmag_cluster-monitor-interval-10" interval="10" name="monitor" timeout="60"/>
<op id="crmag_cluster-monitor-interval-11" interval="11" name="monitor" role="Master" timeout="60"/>
<op id="crmag_cluster-monitor-interval-12" interval="12" name="monitor" role="Slave" timeout="60"/>
<op id="crmag_cluster-notify-interval-0s" interval="0s" name="notify" timeout="60"/>
<op id="crmag_cluster-promote-interval-0s" interval="0s" name="promote" timeout="60"/>
<op id="crmag_cluster-start-interval-0s" interval="0s" name="start" timeout="60"/>
<op id="crmag_cluster-stop-interval-0s" interval="0s" name="stop" timeout="10"/>
</operations>
</primitive>
<meta_attributes id="crmag_cluster-master-meta_attributes">
<nvpair id="crmag_cluster-master-meta_attributes-notify" name="notify" value="true"/>
</meta_attributes>
</master>
<primitive class="ocf" id="virtualip" provider="heartbeat" type="IPaddr2">
<instance_attributes id="virtualip-instance_attributes">
<nvpair id="virtualip-instance_attributes-ip" name="ip" value="192.168.1.15"/>
</instance_attributes>
<operations>
<op id="virtualip-monitor-interval-10s" interval="10s" name="monitor" timeout="20s"/>
<op id="virtualip-start-interval-0s" interval="0s" name="start" timeout="20s"/>
<op id="virtualip-stop-interval-0s" interval="0s" name="stop" timeout="20s"/>
</operations>
</primitive>
</resources>
<constraints>
<rsc_colocation id="colocation-virtualip-crmag_cluster-master-INFINITY" rsc="virtualip" score="INFINITY" with-rsc="crmag_cluster-master" with-rsc-role="master"/>
</constraints>
</configuration>
<status>
<node_state id="1" uname="centos00" in_ccm="true" crmd="online" crm-debug-origin="do_update_resource" join="member" expected="member">
<lrm id="1">
<lrm_resources>
<lrm_resource id="crmag_cluster" type="ag" class="ocf" provider="mssql">
<lrm_rsc_op id="crmag_cluster_last_0" operation_key="crmag_cluster_stop_0" operation="stop" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="4:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" transition-magic="0:0;4:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" exit-reason="" on_node="centos00" call-id="11" rc-code="0" op-status="0" interval="0" last-run="1534864258" last-rc-change="1534864258" exec-time="379" queue-time="0" op-digest="049982ab688a8b6b8895d94c57abc084"/>
<lrm_rsc_op id="crmag_cluster_last_failure_0" operation_key="crmag_cluster_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="2:18:7:bbe48c11-1fd4-4db4-8a3c-2387213b6920" transition-magic="0:8;2:18:7:bbe48c11-1fd4-4db4-8a3c-2387213b6920" exit-reason="" on_node="centos00" call-id="6" rc-code="8" op-status="0" interval="0" last-run="1534864251" last-rc-change="1534864251" exec-time="5697" queue-time="0" op-digest="049982ab688a8b6b8895d94c57abc084"/>
<lrm_rsc_op id="crmag_cluster_pre_notify_demote_0" operation_key="crmag_cluster_notify_0" operation="notify" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="39:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" transition-magic="-1:193;39:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" exit-reason="" on_node="centos00" call-id="-1" rc-code="193" op-status="-1" interval="0" last-run="1534864257" last-rc-change="1534864257" exec-time="0" queue-time="0" op-digest="049982ab688a8b6b8895d94c57abc084"/>
<lrm_rsc_op id="crmag_cluster_post_notify_demote_0" operation_key="crmag_cluster_notify_0" operation="notify" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="40:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" transition-magic="-1:193;40:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" exit-reason="" on_node="centos00" call-id="-1" rc-code="193" op-status="-1" interval="0" last-run="1534864258" last-rc-change="1534864258" exec-time="0" queue-time="0" op-digest="049982ab688a8b6b8895d94c57abc084"/>
<lrm_rsc_op id="crmag_cluster_pre_notify_stop_0" operation_key="crmag_cluster_notify_0" operation="notify" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="38:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" transition-magic="-1:193;38:19:0:bbe48c11-1fd4-4db4-8a3c-2387213b6920" exit-reason="" on_node="centos00" call-id="-1" rc-code="193" op-status="-1" interval="0" last-run="1534864258" last-rc-change="1534864258" exec-time="0" queue-time="0" op-digest="049982ab688a8b6b8895d94c57abc084"/>
</lrm_resource>
<lrm_resource id="virtualip" type="IPaddr2" class="ocf" provider="heartbeat">
<lrm_rsc_op id="virtualip_last_0" operation_key="virtualip_monitor_0" operation="monitor" crm-debug-origin="do_update_resource" crm_feature_set="3.0.14" transition-key="2:21:7:bbe48c11-1fd4-4db4-8a3c-2387213b6920" transition-magic="0:7;2:21:7:bbe48c11-1fd4-4db4-8a3c-2387213b6920" exit-reason="" on_node="centos00" call-id="15" rc-code="7" op-status="0" interval="0" last-run="1534864392" last-rc-change="1534864392" exec-time="111" queue-time="0" op-digest="0dd9b6f76349bef9fdd7ec198ed70063"/>
</lrm_resource>
</lrm_resources>
</lrm>
<transient_attributes id="1">
<instance_attributes id="status-1">
<nvpair id="status-1-master-crmag_cluster" name="master-crmag_cluster" value="20"/>
</instance_attributes>
</transient_attributes>
</node_state>
</status>
</cib>
而正确的写法却是:
代码语言:javascript复制pcs constraint colocation add virtualip crmag_cluster-master INFINITY with-rsc-role=Master
大小写敏感!
13 排序约束
代码语言:javascript复制pcs constraint order promote crmag_cluster-master then start virtualip
> Adding crmag_cluster-master virtualip (kind: Mandatory) (Options: first-action=promote then-action=start)
注意点:
集群资源管理器:
Cluster Resource Manager 比如 Pacemaker
主从库架构配置:
SQL Server Standard 版本只能支持一主一从架构,除了高可用之外,并不支持只读操作,而 Enterprize 版本则可以支持 9 个副本架构,至多 3 个主库,8个从库结构。
集群种类以及故障转移模式:
Cluster Type 是 SQL Server 2017 来新进的特性,有 External 和 None 之分。
External 采用了 Pacemaker 配置。在这种配置下, FailOver 模式也必须是 External( 因此 Failover Mode 也是 SQL Server 2017 以来最新特性, 另外一种模式是 Automatic ).
None 就是不采用 Pacemaker 配置,即便服务器上配置了 Pacemaker, 只要不在 SQL Server AG 中配置 None, 也不会使用 Pacemaker 服务。
从库同步数量 :
required_synchronized_secondaries_to_commit:
AG 使用的配置中,最重要的一个便是它。它控制了与主库强一致性同步的副本数。设置了正确的值,自动故障转移才能顺利执行。根据《Design Data-Intensive Applications》书中介绍,主库的数据可以同步给多个从库,以保证高可用性。在这里,从库的设置便是使用了这个配置,所以它的值可以是以下 3 个:
0 - 没有设置必须同步的从库,自然不能在主库失效的情况下,自动切换从库为主库;
1 - 设置一个从库与主库保持同步,一旦主库失效就可以自动切换负载到从库上;
2 - 设置 2 个同步从库,如同 1 一样,可以自动切主从库。
关于这个主题,可以参考这篇文章,细节谈的更多: Understand SQL Server resource agent for pacemaker https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-availability-group-ha?view=sql-server-2017#pacemakerNotify Always On Availability Groups on Linux https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-availability-group-overview?view=sql-server-2017
随着阅读的深入,就像 Understand SQL Server resource agent for pacemaker 讲的那样,required_synchronized_secondaries_to_commit 指定的数值,并不仅仅是确切的同步副本数量,而是同步副本的数量 / 2 ,即如果集群的同步服务器数量是 3,那么required_synchronized_secondaries_to_commit 就被设置为 1。
这个设置在任何时间都有可能被修改,比如监控节点健康状态时,发现有节点失效了,就要重新计算。3台节点组成的集群,如果其中一个 secondary 节点失效了,那么就会重新计算和保存 required_synchronized_secondaries_to_commit 为1,即在从库副本数据没有更新完之前,主库是不可被访问的。 体现了副本对于可用性与数据保护的影响。
案例:
假如我们的集群是有 8 台节点组成的,其中 1 台是主库, 2 台是同步从库,剩下 5 台是副本节点。那么主库与同步从库之间的数据,始终是保持一致的,那么当其中一台从库失效之后,那么实际上只需要保持一台同步从库同步数据即可,此时 required_synchronized_secondaries_to_commit 即被 Pacemaker Resource Agent 强制设置为 1了。
而当主库失效的时候,必须要有同步库(包括主库和从库)数量减去 required_synchronized_secondaries_to_commit 数量来决定,收到多少个从库的回应,推选主库是有效的。
这里就要思考,如何指定 AG 架构是由 3台同步库(1主2从)组成的?
集群管理器:
集群由一组计算机组成,它提供了高可用和高并发架构。在 SQL Server 中集群的作用是高可用,即所有的工作负载都是引导到一台主机上,如果这台主机失效了,再切换到另一台主机上;在 Oracle RAC 集群中,则是多台计算机共同分担一部分工作负载,如果其中一台主机失效了,会自动切换到那台主机配对的从库上,以此同时保证高可用与高并发。
所以为 SQL Server 搭建的集群,集群管理器负责的事情就是判断失效以及之后的故障转移切换。
扩展下,如何保证集群管理器本身的高可用性?
如果仅仅是配置读写分离,那么可以不用依靠 集群管理器(Cluster Manager), 而仅仅配置 Read-Scale replica.
当然我们这里讨论的是对高可用环境搭建的流程,只读扩展(Read-Scale Replicas) 并不在讨论范围内。3 个同步库的搭建可以完成自动恢复节点,而不仅仅是自动故障时效转移。
测试用例:
实现故障自动切换
每一步配置过后,增加测试配置正确与否的步骤
在最终配置完毕 Availability Groups 的时候,发现数据库对象并不在 3 台集群节点之间同步,而且经常是 3 台节点上的 Availability Groups 中的数据库都无法访问了。
比如遇到新建的 CRMAG Availability Groups 一直对主库进行解析:
The state of the local availability replica in availability group 'crmag' has changed from 'NOT_AVAILABLE' to 'RESOLVING_NORMAL'. The state changed because the local instance of SQL Server is starting up. For more information, see the SQL Server error log or cluster log. If this is a Windows Server Failover Clustering (WSFC) availability group, you can also see the WSFC management console.
从 Log 中发现了有趣的事件,即参加了 availability group 的数据库,并不是随着 instance 的启动而启动了,必须由 availaibility group 启动它。
2018-08-21 23:33:57.31 spid20s Skipping the default startup of database 'crm' because the database belongs to an availability group (Group ID: 65536). The database will be started by the availability group. This is an informational message only. No user action is required.
将所有的 extened events 记录的文件,都拿过来查查错,发现:
Network error code 0x102 occurred while establishing a connection; the connection has been closed. This may have been caused by client or server login timeout expiration. Time spent during login: total 97036 ms, enqueued 0 ms, network writes 0 ms, network reads 0 ms, establishing SSL 97034 ms, network reads during SSL 96934 ms, network writes during SSL 0 ms, secure calls during SSL 100 ms, enqueued during SSL 0 ms, negotiating SSPI 0 ms, network reads during SSPI 0 ms, network writes during SSPI 0 ms, secure calls during SSPI 0 ms, enqueued during SSPI 0 ms, validating login 0 ms, including user-defined login processing 0 ms. [CLIENT: 192.168.1.6]
与 Windows 下安装的异同:
- Microsoft Distributed Transaction Coordinator(DTC) 还不能支持 Linux 版本的 SQL Server 2017 ,因此需要分布式事务的集群部署,还是要架构在 Windows 平台上
- Linux 版本的 SQL Server 部署,使用的是 Pacemaker , 而不是 WSFC(windows server failover cluster). Pacemaker 不需要 Active Directory Domain Services(AD DS)
- 实现故障切换各有各自的方法
- 有些特定属性 比如 required_synchronized_secondaries_to_commit 只能通过 Pacemaker 来实现,而在 Windows 上是通过 T-SQL 也能实现的
参考文章:
- MSDN 文档: https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-setup?view=sql-server-2017
- 云和恩墨张乐奕的文章:https://blog.csdn.net/enmotech/article/details/80267170
- Docker for SQL Server: https://docs.microsoft.com/en-us/sql/linux/quickstart-install-connect-docker?view=sql-server-2017
- SQL Server 镜像下载: https://packages.microsoft.com/
- 介绍在 Centos 上安装 SQL Server 的文章: https://www.rootusers.com/how-to-install-microsoft-sql-server-on-linux/
- How to Set up Nginx High Availability with Pacemaker and Corosync on CentOS7 : https://www.howtoforge.com/tutorial/how-to-set-up-nginx-high-availability-with-pacemaker-corosync-on-centos-7
- MSDN 官方文档之 - Always On Availability Groups on Linux : https://docs.microsoft.com/en-us/sql/linux/sql-server-linux-availability-group-overview?view=sql-server-2017
- MSDN 官方文档之 - An overview of High Availability and Disaster Recovery solutions available for SQL Server https://blogs.msdn.microsoft.com/sql_pfe_blog/2013/06/15/an-overview-of-high-availability-and-disaster-recovery-solutions-available-for-sql-server/
配置 AG 过程遇到的问题集合:
1 两台建立在 台机上的 VM Ware 虚拟机,各自拥有一个 SQL Server 实例,且充当了集群中的从库副本;一台建立在笔记本上的 VM Ware 虚拟机,则充当了集群中的主库副本。在没有安装 pacemaker 的时候,主库上建立的数据库对象,总是不能实时的同步到2个从库中去,且2个从库的同步数据库总是处理不可访问的状态
代码语言:javascript复制消息 976,级别 14,状态 1,第 1 行
The target database, 'crm', is participating in an availability group and is currently not accessible for queries. Either data movement is suspended or the availability replica is not enabled for read access. To allow read-only access to this and other databases in the availability group, enable read access to one or more secondary availability replicas in the group. For more information, see the ALTER AVAILABILITY GROUP statement in SQL Server Books Online.
2 使用台机上的 SSMS 可以无障碍的连接到从库,但连接主库总是掉线。而笔记本上的 SOS(Sql Operation Studio)连接3台都没事。不禁猜想,是主库的某一些设置,导致同步失效。
已成功与服务器建立连接,但是在登录过程中发生错误。 (provider: TCP Provider, error: 0 - 你的主机中的软件中止了一个已建立的连接。) (.Net SqlClient Data Provider)
有关帮助信息,请单击: http://go.microsoft.com/fwlink?ProdName=Microsoft SQL Server&EvtSrc=MSSQLServer&EvtID=10053&LinkId=20476
服务器名称: 192.168.1.10 错误号: 10053 严重性: 20 状态: 0
程序位置:
代码语言:javascript复制在 System.Data.SqlClient.SqlInternalConnectionTds..ctor(DbConnectionPoolIdentity identity, SqlConnectionString connectionOptions, SqlCredential credential, Object providerInfo, String newPassword, SecureString newSecurePassword, Boolean redirectedUserInstance, SqlConnectionString userConnectionOptions, SessionData reconnectSessionData, DbConnectionPool pool, String accessToken, Boolean applyTransientFaultHandling, SqlAuthenticationProviderManager sqlAuthProviderManager)
在 System.Data.SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions options, DbConnectionPoolKey poolKey, Object poolGroupProviderInfo, DbConnectionPool pool, DbConnection owningConnection, DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionFactory.CreateNonPooledConnection(DbConnection owningConnection, DbConnectionPoolGroup poolGroup, DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection)
在 System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
在 System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
在 System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry)
在 System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
在 System.Data.SqlClient.SqlConnection.Open()
在 Microsoft.SqlServer.Management.SqlStudio.Explorer.ObjectExplorerService.ValidateConnection(UIConnectionInfo ci, IServerType server)
在 Microsoft.SqlServer.Management.UI.ConnectionDlg.Connector.ConnectionThreadUser()
但也有可能是 SSMS 17 是比较新的版本,因此不是很稳定,第二次连接就连上了。
- 主库服务器启动后,接着启动从库的服务器,传输消息失败
Aug 23 07:02:03 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[9DDF7B6B-312B-436F-97D1-6DA84DF0DBFF] CHadrTransportReplica State change from HadrSession_Configuring to HadrSession_Timeout - function [CHadrTransportReplica::TimeoutReplica]
Aug 23 07:02:03 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Setting Reconnect Delay to 30 s
Aug 23 07:02:33 centos01 sqlservr[1272]: CHadrTransportReplica::Reset called from function [CHadrTransportReplica::ReconnectTask], primary = 0, primaryConnector = 1
Aug 23 07:02:33 centos01 sqlservr[1272]: CHadrSession State with session ID A1044F08-E3F0-479E-8C23-22FA543E03A4 change from HadrSessionConfig_WaitingSynAck to HadrSessionConfig_ConfigRequest - function [CHadrSession::Reset]
Aug 23 07:02:33 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[1168DDB5-5C01-41D7-B411-81FE9A075B81] CHadrTransportReplica State change from HadrSession_Timeout to HadrSession_Configuring - function [CHadrTransportReplica::Reset_Deregistered]
Aug 23 07:02:33 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104], Seesion:[1168DDB5-5C01-41D7-B411-81FE9A075B81] Queue Timeout (10) from [CHadrTransportReplica::Reset_Deregistered]
Aug 23 07:02:33 centos01 sqlservr[1272]: CHadrSession State with session ID 1168DDB5-5C01-41D7-B411-81FE9A075B81 change from HadrSessionConfig_ConfigRequest to HadrSessionConfig_WaitingSynAck - function [CHadrSession::GenerateConfigMessage]
Aug 23 07:02:43 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[1168DDB5-5C01-41D7-B411-81FE9A075B81] Timeout Detected 10 s
Aug 23 07:02:43 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[1168DDB5-5C01-41D7-B411-81FE9A075B81] CHadrTransportReplica State change from HadrSession_Configuring to HadrSession_Timeout - function [CHadrTransportReplica::TimeoutReplica]
Aug 23 07:02:43 centos01 sqlservr[1272]: [HADR TRANSPORT] AR[8FA8354D-F40F-44EF-A648-722A0ED4F90F]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Setting Reconnect Delay to 30 s
打开第二台从库的时候,状态又有所变化:
代码语言:javascript复制Aug 23 07:18:51 centos02 sqlservr[1307]: CHadrTransportReplica::Reset called from function [CHadrTransportReplica::ReconnectTask], primary = 0, primaryConnector = 1
Aug 23 07:18:51 centos02 sqlservr[1307]: CHadrSession State with session ID 965706DC-2B3D-4E2D-82E0-CAB3ACEC9ED4 change from HadrSessionConfig_WaitingSynAck to HadrSessionConfig_ConfigRequest - function [CHadrSession::Reset]
Aug 23 07:18:51 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[CDF4AEB9-41B8-42C6-B729-28E9378BB4D0] CHadrTransportReplica State change from HadrSession_Timeout to HadrSession_Configuring - function [CHadrTransportReplica::Reset_Deregistered]
Aug 23 07:18:51 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104], Seesion:[CDF4AEB9-41B8-42C6-B729-28E9378BB4D0] Queue Timeout (10) from [CHadrTransportReplica::Reset_Deregistered]
Aug 23 07:18:51 centos02 sqlservr[1307]: CHadrSession State with session ID CDF4AEB9-41B8-42C6-B729-28E9378BB4D0 change from HadrSessionConfig_ConfigRequest to HadrSessionConfig_WaitingSynAck - function [CHadrSession::GenerateConfigMessage]
Aug 23 07:18:53 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Transport is not in a connected state, unable to send packet
Aug 23 07:18:57 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Transport is not in a connected state, unable to send packet
Aug 23 07:19:01 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[CDF4AEB9-41B8-42C6-B729-28E9378BB4D0] Timeout Detected 10 s
Aug 23 07:19:01 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Session:[CDF4AEB9-41B8-42C6-B729-28E9378BB4D0] CHadrTransportReplica State change from HadrSession_Configuring to HadrSession_Timeout - function [CHadrTransportReplica::TimeoutReplica]
Aug 23 07:19:01 centos02 sqlservr[1307]: [HADR TRANSPORT] AR[D55252F0-9CBA-4D36-87B2-246248A0C846]->[071D8AF0-0B68-4AA9-9041-A06B28FC2104] Setting Reconnect Delay to 9 s
Transport is not in a connected state, unable to send packet
这似乎说明,这三台集群节点之间并不能互相通信。 又或者说明作为 Service Broker Endpoint 之间,没有认证的通信授权。
放出一张截图,经历了各种蹂躏,失败以及怀疑人生之后的景象:
所有的连接如果指向的是 192.168.1.15 那么背后的 sql server instance 自动切换,都不会影响到应用对数据库的访问。借用《子弹飞》里刘嘉玲的那句话,“我只想当县长夫人,至于县长是谁,那并不重要!”。