AlwaysOn实现只读路由
1.配置只读路由
①配置A副本的只读路由属性(ReadOnly代表‘只读意向’)
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
②配置A副本的只读路由URL
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'tcp://WIN-14VNU7CGQO1.fnst.com:1433'));
③配置B副本的只读路由属性
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO2' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
④配置B副本的只读路由URL
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO2' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'tcp://WIN-14VNU7CGQO2.fnst.com:1433'));
⑤配置A副本作为主副本时候的只读路由表
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO1' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('WIN-14VNU7CGQO2','WIN-14VNU7CGQO1')));
⑥配置B副本作为主副本时候的只读路由表
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N'WIN-14VNU7CGQO2' WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=('WIN-14VNU7CGQO1','WIN-14VNU7CGQO2')));
配置完成后:使用 SELECT * FROM sys.availability_read_only_routing_lists 查看路由表
确认一下应该是下面的形式 :
A B
A A
B A
B B
为什么这么配置请分析如下过程
1.正常运行时候,A作为主副本,B作为辅助副本,客户端连接字符串指定数据源是侦听器地址
2.此时发送只读请求
3.侦听器收到只读数据请求,有主副本A来处理,主副本A发现是ReadOnly,就查询路由表,发现第一条符合,就把只读请求交给辅助副本B来处理
4.此时主副本A失效了,那么由AlwaysOn的高可用可知,会让辅助B作为了主副本,等原来的主副本A恢复之后,让A成为新的辅助副本(当然这些对客户端是透明的)
5.副本A恢复之后,再发送一条只读请求
6.此时侦听器使用主副本B来处理这个请求,如果不像上面的设置方法,就找不到B到A的路由,也就不能实现所谓的高可用
2.配置的确认
例如:有一个可用组testAG,其中有两个副本A和B,其中主副本为A,辅助副本为B,并且在AlwaysOn可用组内设定了Listener
A和B的配置如下:
3.测试只读路由
客户端程序中指定连接字符串:connectStr = "Data Source=tcp:193.160.26.30,1433;Initial Catalog=test;Integrated Security=True;ApplicationIntent=ReadOnly;MultiSubnetFailover=True";
重要参数说明:
DataSource:tcp:193.160.26.30,1433 这个填写的是侦听器的地址
ApplicationIntent=ReadOnly 说明这个连接是一个只读意向的连接,这样的情况下,请求发送到主副本A上,主副本发现是只读的请求会先产看只读路由表,然后通过
主副本A转发到辅助副本B上
会出现的问题: 如果客户端这时候的连接字符串指定了ApplicationIntent=ReadOnly,它只表明这是一个只读意向的请求,但是不能保证请求一点是只读的,如果是写请求
就会出现失败的情况。所以在进行写操作的时候不能设置这个选项。
测试程序如下:
主副本: 192.168.24.28
辅助副本:192.168.24.32
侦听器:192.168.24.30:1433
代码如下:
namespace AlwaysonTest
{
public partial class Form1 : Form
{ public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
} private void btnInsert_Click(object sender, EventArgs e)
{ Thread t = new Thread(Write);
t.IsBackground = true;
t.Start(); } private void btnReadData_Click(object sender, EventArgs e)
{ Thread t = new Thread(Read);
t.IsBackground = true;
t.Start();
} public void Write()
{
string name = System.DateTime.Now.ToString();
//插入数据的时候,连接字符串不指定ReadOnly
string connectStrW = "Data Source=tcp:193.160.26.30,1433;Initial Catalog=test;Integrated Security=True;MultiSubnetFailover=True"; int count = Convert.ToInt32(textBox4.Text); using (SqlConnection conn = new SqlConnection(connectStrW))
{
for (var i = ; i <= count; i++)
{
conn.Open();//打开数据库
//创建数据库命令
SqlCommand cmd = conn.CreateCommand();
//创建查询语句 在写的操作过程中,写之前先读操作,测试不加ReadOnly时候只读路由有没有效果
cmd.CommandText = "select count(*) from test1";
int x = (int)cmd.ExecuteScalar();
//创建查询语句 Thread.Sleep();
cmd.CommandText = "Insert into test1 values" + '(' + '\'' + name + '\'' + ')';
cmd.ExecuteNonQuery();
textBox1.Text = (x + i).ToString();
conn.Close();
}
} } public void Read()
{ //查询数据的时候,连接字符串指定ReadOnly
string connectStr = "Data Source=tcp:193.160.26.30,1433;Initial Catalog=test;Integrated Security=True;ApplicationIntent=ReadOnly;MultiSubnetFailover=True"; int count = Convert.ToInt32(textBox4.Text); for (var j = ; j <= count; j++)
{
Thread.Sleep();
using (SqlConnection conn = new SqlConnection(connectStr))
{
conn.Open();//打开数据库
//创建数据库命令
SqlCommand cmd = conn.CreateCommand();
//创建查询语句
cmd.CommandText = "select count(*) from test1";
int x = (int)cmd.ExecuteScalar();
textBox2.Text = x.ToString();
conn.Close();
}
} } }
}
检测结果:
开始之前,打开Sql Server Profiler进行数据的分析。
如下图所示,为了排除干扰,发现程序执行前是没有数据的读写的。
测试点一: 写操作不加ReadOnly限制,是不是能够在主副本写成功
结果如下图,
结论:因为只有主副本有操作记录,可以说明是在主副本进行写入成功的
测试点二:读操作加上ReadOnly限制,它的处理副本是主副本还是辅助副本(清除上次记录)
结果如下图:
结论:左侧主副本的内容和我们的查询内容无关,右侧辅助副本全部都是我们的查询操作,所以可以证明存在ReadOnly的时候读操作都被辅助副本执行
测试点三:读操作不加ReadOnly限制,它的处理副本是主副本还是辅助副本
Read()操作中连接字符串去掉ApplicationIntent=ReadOnly,并清空上面操作信息,然后执行程序
结论:在不加ReadOnly选项的时候,读操作全部有主副本进行了处理
测试点四:写操作加上ReadOnly限制,能够被主副本进行处理
在Write()中连接字符串中加上ApplicationIntent=ReadOnly,清空上面操作记录,执行程序
结论:上图可以知道,在写操作的时候,如果有ReadOnly会报错
AlwaysOn实现只读路由的更多相关文章
- SQL 2012 alwayson设置只读路由
ALTER AVAILABILITY GROUP [sqlmaxiangqianbd] MODIFY REPLICA ON N'maxiangqian1' WITH (SECONDARY_R ...
- sql server alwayson 可用性组 只读路由的设置
昨天晚上学习了[SQL Server 2012实施与管理实战指南]的第三章,于是今天想在前段时间建的那个alwayson 可用性组测试环境上也配置一下只读路由,尝试实现读写分离. 按照书中的方法,执行 ...
- SQL Server Alwayson配置两个节点加共享文件夹仲裁见证
标签:MSSQL/节点和共享文件夹多数 概述 之前讲过多数节点的仲裁配置,多数节点一般3个节点以上的奇数个节点:常见的是使用3个节点节点多了也是浪费因为Alwayson的只读路由只能利用到一个只读副本 ...
- SQL Server ->> 高可用与灾难恢复(HADR)技术 -- AlwaysOn可用性组(理论篇)
因为篇幅原因,AlwaysOn可用性组被拆成了两部分:理论部分和实战部分.而实战部分又被拆成了准备工作和AlwaysOn可用性组搭建. 三篇文章各自的链接: SQL Server ->> ...
- 虚IP解决程序连只读服务器故障漂移
目前公司有一套核心交易数据库配置了AlWaysON,SQL 2012版本, 1主4从, 其从库(8,14, 8.15) 这2台只读的从数据库服务器, 后台程序和wms等很多程序,都是直接配置IP连接这 ...
- 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://w ...
- (转) 从0开始搭建SQL Server AlwaysOn 第三篇(配置AlwaysOn)
原文地址: http://www.cnblogs.com/lyhabc/p/4682986.html 这一篇是从0开始搭建SQL Server AlwaysOn 的第三篇,这一篇才真正开始搭建Alwa ...
- SQL Server AlwaysOn
标签:SQL SERVER/MSSQL SERVER/数据库/DBA/高性能解决方案 概述 环境: 域服务器:windows server 2008 R2 SP1,192.168.2.10 DNS:1 ...
- [AlwaysOn Availability Groups]排查:AG配置
排查AG配置 本文主要用来帮助排查在AG配置时出现的问题,包括,AG功能被禁用,账号配置不正确,数据库镜像endpoint不存在,endpoint不能访问. Section Description A ...
随机推荐
- Java中的IP对象以及本地域名解析
本地域名解析操作步骤: 1.打开C:\WINDOWS\system32\drivers\etc目录 2.找到host文件,用记事本打开 3.添加“空间IP 域名” package WebProgra ...
- 备份数据表为insert 脚本
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- 将NavigationBar设置透明
将NavigationBar设置透明(仅将指定视图控制器进行透明处理),步骤如下:1.在视图控制器的头文件中实现UINavigationControllerDelegate,例如:@interface ...
- 在CentOS 6.2上安装 MemcacheQ 最新版
1. 安装 yum install gcc cc make libevent libevent-devel 2. 安装Berkeley DB 下载:http://www.oracl ...
- web.xml(spring/spring mvc/hibernate)
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" ...
- CentOS6.5安装telnet
原文地址:http://www.cnblogs.com/zhongshengzhen/ 1.检查是否已经安装telnet [root@localhost ~]# rpm -qa | grep teln ...
- SQLite 使用教程2 语法
http://www.runoob.com/sqlite/sqlite-syntax.html SQLite 语法 SQLite 是遵循一套独特的称为语法的规则和准则.本教程列出了所有基本的 SQLi ...
- Windows 7 EXE图标丢失修复方法
有过Win7下的一些EXE文件图标莫名奇妙丢失,但功能却正常的情况吗?这是图标缓存的问题,应该是Win7的bug. 在命令提示符下输入下列命令即可恢复. 以下是代码片段: taskkill /im e ...
- javascript 递归之阶乘
阶乘,即5! = 5*4*3*2*1, 先看传统的做法,利用while循环实现: function factorial(num){ var result = num; if(num<0){ re ...
- IPVS
http://kb.linuxvirtualserver.org/wiki/IPVS_FULLNAT_and_SYNPROXY