SQL Server 2017 AlwaysOn可用性组只读请求未路由至辅助服务器
解决AlwaysOn只读路由失效的问题
咱们一步步排查常见的问题点,先从最容易踩坑的地方开始:
1. 先确认只读路由URL的端口是否正确
你现在设置的READ_ONLY_ROUTING_URL用了5022端口,这个一般是AlwaysOn可用性组端点的通信端口,但只读路由需要指向SQL Server数据库引擎的监听端口(默认是1433,如果你改过端口就是自定义的那个)。
先在两个副本上执行这个查询,拿到数据库引擎的实际端口:
SELECT local_tcp_port FROM sys.dm_exec_connections WHERE session_id = @@SPID;
然后更新只读路由URL,把端口换成上面查到的数值:
ALTER AVAILABILITY GROUP [DEV-SQLAG] MODIFY REPLICA ON N'DEV-DB1' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://Dev-DB1.test.com:1433')); -- 替换为实际查到的端口 ALTER AVAILABILITY GROUP [DEV-SQLAG] MODIFY REPLICA ON N'DEV-DB2' WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N'TCP://Dev-DB2.test.com:1433')); -- 替换为实际查到的端口
2. 检查副本是否允许只读连接
确保副本的secondary角色允许只读连接,执行这个查询看看:
SELECT replica_server_name, secondary_role_allow_connections FROM sys.availability_replicas WHERE group_id = (SELECT group_id FROM sys.availability_groups WHERE name = 'DEV-SQLAG');
如果secondary_role_allow_connections的值是0(表示NO),就得改成允许只读:
ALTER AVAILABILITY GROUP [DEV-SQLAG] MODIFY REPLICA ON N'DEV-DB1' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY)); ALTER AVAILABILITY GROUP [DEV-SQLAG] MODIFY REPLICA ON N'DEV-DB2' WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
3. 验证连接时的只读意图是否正确设置
你用SSMS通过监听器连接时,一定要确认只读意图已经生效:
- 连接窗口点击「选项」,在「连接属性」里勾选「只读意图」;或者在「附加连接参数」里输入
;ApplicationIntent=ReadOnly - 也可以用sqlcmd直接测试,更准确:
替换成你实际的监听器和数据库名称,看看返回的是不是从节点。sqlcmd -S 你的监听器名称 -d 要连接的数据库名 -K ReadOnly -Q "SELECT @@SERVERNAME;"
4. 检查副本的同步状态
如果是同步提交模式的AG,得确保副本已经同步完成,不然只读路由不会路由到未同步的副本:
SELECT replica_server_name, synchronization_state_desc FROM sys.dm_hadr_database_replica_states WHERE group_id = (SELECT group_id FROM sys.availability_groups WHERE name = 'DEV-SQLAG');
如果状态是NOT SYNCHRONIZED,先等同步完成,或者检查日志传送有没有问题。
5. 查看错误日志找线索
如果上面的步骤都没解决,去SQL Server的错误日志里搜「read only routing」相关的条目,里面会明确告诉你失败的原因,比如端口不通、权限问题、配置没生效之类的。
最大概率的问题就是第一步的端口搞错了,先改这个试试!
内容的提问来源于stack exchange,提问作者Tomasz




