Alwayson支持的,是一个可用性组,每个可用性组是包含了多个用户数据库的容器,可用性组内的数据库可以作为一个整体进行故障转移。
AlwaysOn关键特性:
一、类似集群的特性
1.多个数据库可以一起迁移
2.提供一个虚拟服务器名,这个虚拟服务器名始终是当前的primary。
3.可以有自动切换,手动切换和强制切换
4.一个primary,最多4个secondary(sql server 2014增加到了8个)
5.Dashborad可以监视alwayson运行状况
6.依赖于windows 2008集群,实现多站点部署。
二、类似镜像的特性:
1.每个secondary上有一份数据复制,可以支持只读请求
2.可以在secondary执行备份和dbcc命令
3.在配置情况下,只读请求可以被重定向到secondary
4.自动修复某些类型数据页的损坏
5.primary和secondary之间的数据被加密和压缩,提高安全性和减少流量。
目录
<a href="#_Toc386629478">3.AlwaysOn可用组... 1</a>
<a href="#_Toc386629479">3.1 AlwaysOn基本架构... 1</a>
<a href="#_Toc386629480">3.2 AlwaysOn数据同步原理... 2</a>
<a href="#_Toc386629481">3.3 AlwaysOn可用性模式... 2</a>
<a href="#_Toc386629482">3.3.3可用副本之间“DISCONNECTED”状态... 3</a>
<a href="#_Toc386629483">3.3.4 Secondary的”NOT SYNCHRONIZING”状态... 3</a>
<a href="#_Toc386629484">3.4 AlwaysOn故障转移... 4</a>
<a href="#_Toc386629485">3.4.1自动故障转移... 4</a>
<a href="#_Toc386629486">3.4.2 手动故障转移... 4</a>
<a href="#_Toc386629487">3.4.3强制故障转移... 5</a>
<a href="#_Toc386629488">3.4.4 多子网可用性组故障转移... 5</a>
<a href="#_Toc386629489">3.4.5 Split Brain(大脑分裂)5</a>
<a href="#_Toc386629490">3.4.6 连接,可用性副本和可用性数据库状态... 5</a>
<a href="#_Toc386629491">3.5 创建一个Always可用性组... 5</a>
<a href="#_Toc386629492">3.6 可读的Secondary. 5</a>
<a href="#_Toc386629493">3.6.1 ApplicationIntent. 5</a>
<a href="#_Toc386629494">3.6.2 副本可读模式设置... 6</a>
<a href="#_Toc386629495">3.6.3只读路由... 6</a>
<a href="#_Toc386629496">3.6.4 secondary上可能出现的性能问题... 7</a>
<a href="#_Toc386629497">3.6.5 统计信息... 7</a>
<a href="#_Toc386629498">3.7 监控AlwaysOn可用性组的运行状态... 8</a>
AlwaysOn的可用性组包含一个或者多个数据库,这些数据库被称为可用性数据库。每个secondary上都有这些数据库的副本。这些数据库彼此之间是同步的。
AlwaysOn可用性组从windows集群角度看是一个集群资源,可用性数据库在集群的节点之间进行迁移。AlwaysOn不能应用到系统数据库,不能保证系统数据库的高可用性。
在AlwaysOn成员内,只有一个成员是可读写的,称为主数据库(Primary),其他的叫副本(secondary)。
限制:
1.可用性组运行在一个windows集群上,不能跨集群
2.可用性成员要在不同的windows集群节点上
3.如果集中一个可用性成员是一个sql集群,那么这个集群上的其他非活跃节点上安装的实例不能成为这个可用性组的副本
4.一个数据库只能属于一个可用性组
Listener:AlwaysOn重要的组件之一,可以让应用程序透明的连接到primary。
Listener由虚拟ip地址,虚拟DNS,端口号组成。创建完Listener之后,会为当前primary添加虚拟ip和虚拟DNS。这样就可以透明的访问primary。SQL Server 2012支持在启动状态下绑定ip地址,DNS,端口来完成这个功能。
Listener不会使用sql browser,listener会以默认实例方式连接。
如果Listener的端口是1433端口(可以和实例共享端口),那么可以很简单的直接使用虚拟网络名连接到副本。如果Listener使用的是非默认端口:
1.如果primary监听1433端口,那么直接用DNS就可以访问了。
2.如果primary监听的不是1433端口,那么客户端必须在连接字符串中指定端口号才能连接到primary。(从SQL Server 2012 SP1测试看可以是listener的端口,也可以是primary监听的端口)
建议所有节点使用相同的监听端口,不然故障转移之后可能导致listener无法访问primary。
AlwaysOn要把primary上的变化同步给secondary,所以要完成以下几件事情:
1.把primary上的修改记录下来
2.把修改传输到副本
3.把修改应用到副本
AlwaysOn完成以上事情的步骤:
1.使用Log Write线程,负责把日志信息写入到内存的log buffer上,然后log buffer 写入到磁盘(固化)。
2.primary有个工作线程log scanner,将log buffer中的日志读出来,打包成日志块传输给secondary
3.在secondary上2个线程,redo和harden。Harden负责将发送过来的日志快写入到日志文件中。Redo负责将日志记录翻译成修改操作,在辅助数据库上完成。
AlwaysOn有2个可用性模式:异步提交,同步提交
和数据库镜像类似,不多介绍。
日志同步步骤
步骤
行为
连接
通过镜像端点连接
请求数据
发起一个请求到primary,要求发送日志块,双方协商出一个LSN
运行Log Scanner
Log Scanner运行,将日志块发送到secondary
固化和重做日志
Secondary固化和重做线程来处理log scanner发送过来的日志块,固化将日志块固化到硬盘,重做线程将日志重做
反馈进度
当secondary收到primary3个消息,就会反馈进度,如果超过1秒没有3条,也会反馈进度,进度信息包含了哪些LSN被应用到了secondary。
事务提交步骤
提交事务
在primary上执行commit
写入到本地日志记录
Primary上commit会被写入成一条日志记录,log writer会把知道commit为止的日志,全部写入到LDF文件。当写入磁盘后,primary等待secondary成功固化的消息
扫描日志
当日志块被写入到磁盘,给Log Scanner信号,开始工作。把日志发送给日志块解码器,解码器会搜索要特殊处理的操作,这些特殊操作解码器会以一个消息发送给secondary。如果解码完毕,整个日志块被发送给secondary
处理日志块消息
收到日志块,被固化和重做
完成提交
Primary收到了secondary的确认,完成事务提交并发送给客户端确认
当primary为复制的发布数据库,那么log reader代理程序不会去处理那些没有被secondary固化的日志,这样做的目的是当复制发送数据比较快的时候,当secondary变成primary,就可能发送订阅数据库的数据比发布数据库新的问题。
副本之间会固定间隔发送ping,如果在超时期间内收到ping,那么正常。收到之后副本会重置连接上的超时计数器。Primary和secondary通过ping来判断批次是否依旧处于活动状态。
如果ping超时,那么primary和secondary连接户进入disconnected状态。
回话超时限制可以设置,默认为10s,最小允许5s。一般建议大于10s。
如果一个事务在secondary上重做失败,那么secondary的数据库会进入 not synchronizing状态。
AlwaysOn依赖Windows故障转移集群。AlwaysOn需要一个集群Resource DLL来连接到Windows集群和SQL Server实例。Windows集群需要透过AlwaysOn的Resource DLL来控制资源的上线和离线。
AlwaysOn的可用性组的资源是“SQL Server Availability Group”Resource DLL叫Hadrres.DLL,并在Hadrres.exe定义了可用性组isalive的检查方法。
注意点:
1.可用性组也是集群资源,healthchecktimeout为30000毫秒。
2.无论有多少个可用性组,只有一条sp_server_diagnostics来诊断可用性组。
3.sp_server_diagnostics用来检查实例的健康,而不是检查每个数据库的状态。
Alwayson发生故障之后,是否会立刻故障转移,去决议可用性模式和故障转移模式的设置.
异步提交
同步提交,手动故障转移
同步提交,自动故障转移
自动故障转移
不支持
支持
手动故障转移
强制故障转移
自动故障转移和手动故障转移都要求故障转移目标是使用同步提交模式并且处于SYNCHRONIZED状态的secondary。
异步提交的只能使用强制故障转移。
要求条件:
1.当前primary和secondary都设置为同步模式并且是自动故障转移模式
2.primary和secondary必须是同步的
3.primary边的不可用
步骤:
1.如果当前primary在运行,会把primary和secondary的连接断开
2.如果secondary上面有没有完成的日志,secondary会继续执行redo,完成secondary的前滚。
3.前滚完成,secondary变成primary
4.新的primary在连接到一个secondary之前,不管前滚是否结束会把自己的状态设置为NOTSYNCHRONIZED,只有当secondary连接到primary,primary会变成SYNCHRONIZED。
5.当老的primary重启之后,发现其他人变成primary,会把自己变成secondary。
当primary和secondary处理SYNCHRONIZED状态,就可以执行手动故障转移,如果primary停止运行,secondary就会进入RESOLVEING角色,RESOLVEING是一个角色不是状态,和primary和secondary类似。可以执行强制故障转移,但是会丢失数据。
方法:
1.直接用windows故障转移管理器
2.使用TSQL
3.使用SSMS UI
4.使用powershell
注意:只有为自动故障转移模式的可用性副本才能使用windos故障转移管理器。
强制故障转移和镜像的类似,会有可能会照成数据丢失。
要在客户端链接字符串的MultiSubnetFailover参数设置为true。除支持外必须通过listener来访问可用性副本。
大脑分裂就是,在一个可用性组里面出现了2个primary。这个是不被允许的。可用性组资源属性中有一个leasetimeout,windows会定期的和windows集群认为的primary通信,如果leasetimeout都没有收到windows集群的确认消息,那么副本就认为自己被切换掉了。
略
AlwaysOn中secondary可以做只读,来分担读负荷。
要让只读操作能够透明的被自动转向到secondary,要解决一下三个问题:
1.客户端要标记自己的操作时只读的
2.secondary要被设置为可读
3.客户端连接,要被重定向才能到secondary,需要只读路由。
AplicationIntent用来标记客户端发送来的请求类型:
ApplicationIntent = ReadOnly
ApplicationIntent = ReadWrite
Secondary访问方式有3中:
1.NONE:辅助数据库不接受任何类型的数据访问
2.READ_ONLY:和自由applicationintent=ReadOnly是可以访问
3.ALL:任何链接都可以连接,但是只有只读操作可以执行
Primary访问类型只有ReadWrite和ALL。
如果Primary为ReadWrite,客户端连接字符串中指定了ApplicationInit为ReadOnly,并指向了Primary,那么访问会被拒绝。
实现只读路由需要以下条件:
1.客户端要使用TCP协议,通过Listener连接到primary
2.客户端连接字符串ApplicationIntent=ReadOnly
3.至少有一个secondary被配置为ALL或者READONLY
4.为secondary配置只读路由URL和在primary中的只读路由列表
ALTERAVAILABILITYGROUP [AG1]
MODIFYREPLICAON
N'COMPUTER01'WITH
(SECONDARY_ROLE (ALLOW_CONNECTIONS=READ_ONLY));
ALTERAVAILABILITYGROUP [AG1]
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL =N'TCP://COMPUTER01.contoso.com:1433'));
N'COMPUTER02'WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL =N'TCP://COMPUTER02.contoso.com:1433'));
MODIFYREPLICAON
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('COMPUTER02','COMPUTER01')));
(PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('COMPUTER01','COMPUTER02')));
GO
1.连接请求会首先被直到primary上
2.primary检查目标数据库,确认该数据库属于可用性组
3.如果属于,检查只读路由列表,如果没有只读路由列表,只读路由不会工作
4.若发现只读路由,会依次检查列表,直到发现第一个访问模式设置为READONLY或者 ALL的secondar。
5.primary把只读路由URL通过TDS发送给客户端
6.客户端重新定向到secondary。
因为secondary上同时存在读写,所以会存在堵塞的情况,为了保证只读的性能,AlwaysON会使用行版本控制来消除堵塞问题
复杂查询的运行也会影响日志redo,尽量在业务低谷期运行这些查询
Secondary上可以用索引,但是不能创建索引,所以要用的时候要在primary上创建
因为secondary只读,所以只能在primary创建统计信息,然后同步到secondary。Alwayson会在tempdb上创建临时的统计信息。来替代永久的 统计信息。
临时统计信息以_readonly_database_statistic后缀。