故障转移后数据库写入保护:程序连接AG集群写入失败求助
检查故障转移后的副本角色与数据库状态
执行以下查询确认目标数据库的读写状态:SELECT name, state_desc, is_read_only FROM sys.databases WHERE name = 'XY';如果
is_read_only返回1,说明数据库处于只读状态。同时验证副本同步状态:SELECT synchronization_state_desc, is_failover_ready FROM sys.dm_hadr_database_replica_states WHERE database_id = DB_ID('XY');需确保
synchronization_state_desc为SYNCHRONIZED且is_failover_ready为1,否则故障转移可能未完成,数据库暂时只读以保护数据。验证连接字符串的应用意向配置
检查程序连接字符串是否包含ApplicationIntent=ReadOnly参数——即使连接到主副本,该参数会强制路由到只读副本,导致写入失败。将其修改为ApplicationIntent=ReadWrite或直接移除该参数。同时通过会话验证实际连接的实例:SELECT @@SERVERNAME;确认连接的是故障转移后的主实例。
检查可用性组副本的读写意向配置
确认故障转移后的主副本在AG属性中,读写意向设置为“读/写”。虽然主副本默认应为读写,但配置异常可能导致其被标记为只读意向,限制写入操作。排查登录名SID一致性
即使使用官方工具迁移了权限,仍需验证登录名的SID在两个实例上完全一致:SELECT name, sid FROM sys.server_principals WHERE name = '你的程序登录名';若SID不一致,会导致数据库用户与登录名的映射失效,实际会话无写入权限(表现为只读错误)。此时需删除目标实例的登录名,使用带SID参数的
CREATE LOGIN语句重新创建,确保与源实例SID匹配。尝试手动解除数据库只读状态
若上述检查均正常,执行以下语句尝试恢复数据库可写状态:ALTER DATABASE XY SET READ_WRITE;若执行成功,说明故障转移过程中出现了异常的只读标记,需排查AG故障转移的日志事件,确认是否存在同步中断或其他异常。
内容的提问来源于stack exchange,提问作者SikorskyS60

