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

SQL Server 2017可用性组场景下,如何限制sys.databases仅返回可连接数据库?

过滤SQL Server 2017可用性组架构中可连接的可用数据库

嘿,在SQL Server可用性组(AG)架构下遇到这个问题太正常了——毕竟副本节点上的sys.databases会列出AG里所有数据库的副本,其中不少是处于不可连接或者未就绪状态的,完全不符合你的需求对吧?下面给你一套精准的解决方案:

核心过滤查询

这个查询会帮你筛选出真正可连接、处于可用状态的数据库,不管是主副本还是允许访问的只读副本:

SELECT 
    name, 
    state,
    state_desc,
    is_read_only
FROM sys.databases
LEFT JOIN sys.dm_hadr_database_replica_states drs 
    ON sys.databases.database_id = drs.database_id
WHERE 
    -- 可选:排除master、model、msdb、tempdb这四个系统库,按需调整
    database_id > 4
    -- 只保留在线状态的数据库,排除还原、恢复、离线等不可连接状态
    AND state = 0 
    AND (
        -- 非AG架构的普通数据库直接保留
        drs.replica_id IS NULL
        -- AG数据库:区分主副本和可访问的副本节点
        OR (
            drs.replica_id IS NOT NULL 
            AND (
                -- 主副本上的数据库,支持读写连接
                drs.role_desc = 'PRIMARY'
                -- 副本节点:允许外部连接,且数据库处于只读可用状态
                OR (
                    drs.role_desc = 'SECONDARY' 
                    AND sys.databases.is_read_only = 1 
                    AND drs.secondary_role_allow_connections_desc IN ('ALL', 'READ_ONLY')
                )
            )
        )
    )

关键条件解释

  • database_id > 4:如果你不需要显示系统库,可以保留这个条件;如果要包含系统库,直接删掉就行。
  • state = 0:对应state_desc = 'ONLINE',确保数据库处于可连接的在线状态。
  • drs.replica_id IS NULL:照顾那些不在AG里的普通数据库,保证原有非AG场景的兼容性。
  • 针对AG数据库的逻辑:
    • 主副本的数据库天然支持读写连接,直接保留。
    • 副本节点需要满足两个条件:一是副本配置允许外部连接(secondary_role_allow_connections_desc设为ALL或READ_ONLY),二是数据库本身处于只读可用状态(is_read_only = 1)。

进阶优化(可选)

如果你的环境有异步提交模式的副本,建议加上同步状态过滤,避免连接到未完全同步的数据库:

SELECT 
    name, 
    state,
    state_desc,
    is_read_only,
    synchronization_state_desc
FROM sys.databases
LEFT JOIN sys.dm_hadr_database_replica_states drs 
    ON sys.databases.database_id = drs.database_id
WHERE 
    database_id > 4
    AND state = 0 
    AND (
        drs.replica_id IS NULL
        OR (
            drs.role_desc = 'PRIMARY'
            OR (
                drs.role_desc = 'SECONDARY' 
                AND sys.databases.is_read_only = 1 
                AND drs.secondary_role_allow_connections_desc IN ('ALL', 'READ_ONLY')
                -- 确保副本数据已同步完成
                AND drs.synchronization_state_desc = 'SYNCHRONIZED'
            )
        )
    )

这样调整后,返回的结果就是所有用户可以正常连接并执行操作(读写或只读,取决于副本角色)的数据库了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:25:58