You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Azure App Service连接Azure SQL只读异地副本未生效及用户创建错误的问题排查

排查Azure SQL只读副本连接问题的实操指南

我来帮你拆解这两个连接问题的核心原因和排查步骤,都是Azure SQL只读副本配置里很容易踩的坑:

一、为什么加了ApplicationIntent=ReadOnly还是走主库?

这核心是你对这个参数的适用场景理解错了,结合你的副本配置(独立SQL Server实例、数据库名称和主库不一样),这里有两个关键错误:

  • 第一个错:ApplicationIntent=ReadOnly的自动路由有严格的架构要求
    这个参数只在两种情况下能自动把读请求转到副本:

    1. 你的可读副本是同一个逻辑SQL Server实例下的次要副本(比如Always On可用性组的副本);
    2. 或者是官方的异地复制可读副本,且副本数据库名称和主库完全一致,同时你连接的是主服务器的终结点。
      而你的副本在单独的SQL Server实例,数据库名还不一样,Azure SQL根本没法识别它是主库的只读副本,自然不会帮你路由请求。
  • 第二个错:你可能搞错了连接字符串的目标
    如果就是想直接连这个独立的只读副本,那根本不需要加ApplicationIntent=ReadOnly,直接用副本所在SQL Server的连接字符串,指向副本的数据库名就行。但这种方式没法自动故障转移,要是需要自动路由的话,你得调整副本架构——要么把副本改成同实例的次要副本,要么用官方异地复制确保库名一致。

怎么验证?

你可以在主库和副本库分别跑下面的SQL,看看连接的实际属性:

SELECT 
    session_id, 
    host_name, 
    program_name, 
    application_intent, 
    db_name(database_id) AS connected_db
FROM sys.dm_exec_sessions
WHERE is_user_process = 1

如果你的连接里application_intent显示ReadOnly,但connected_db却是主库,那肯定是路由没生效,问题就出在副本架构不符合自动路由的要求。

二、为什么用副本用户连接时报错“数据库是只读的”?

这个报错看似矛盾,其实原因很明确:

  • 要么你代码里不小心执行了写操作——哪怕是你没注意到的,比如ORM框架自动跑的迁移脚本、默认的INSERT/UPDATE语句,或者某些初始化操作,只读副本完全不允许任何写操作,哪怕是只读用户也不行;
  • 要么你给用户配的权限不对——如果用户有ALTER之类的写权限,哪怕数据库是只读的,执行写操作时也会触发这个错误。

怎么排查?

  1. 先检查代码,确保所有针对副本的请求都是纯查询(SELECT为主),没有任何修改数据库的语句;
  2. 重新给副本用户配置只读权限,在副本库执行:
-- 如果你用的是SQL用户,替换成你的用户名和密码
CREATE USER [replica_user] WITH PASSWORD = '你的密码';
ALTER ROLE db_datareader ADD MEMBER [replica_user];
  1. 确认连接字符串里明确指向了副本的数据库名称,别让代码误连到主库。

总结你操作里的错误点:

  1. 错误地认为ApplicationIntent=ReadOnly能路由到独立SQL Server实例、名称不同的只读副本,这个参数根本不支持这种场景;
  2. 使用副本用户连接时,要么代码里有写操作,要么用户权限配置不当,触发了只读数据库的写错误。

内容的提问来源于stack exchange,提问作者Angela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:47:51