我已经阅读了有关只读路由的 MS 文档,但我不是在谈论这个。
目前,如果我UPDATE
对位于辅助副本上且属于可用性组的数据库执行操作,我会收到一条消息:
Msg 3906, Level 16, State 2, Line 6
Failed to update database "dbName" because the database is read-only.
我的问题是,由于数据库是 AG 的一部分并且目前在辅助节点上,这种配置是否是默认建立的(并且是不可避免的)?
一些有趣的额外内容:
以下 SQL 在该辅助节点上运行,显示 I haveUPDATE
以及ALTER
对该数据库的更多权限:
SELECT *
FROM fn_my_permissions(null, 'DATABASE')
ORDER BY subentity_name, permission_name;
以下 SQL 明确显示我有权访问UPDATE
该数据库中的表:
SELECT *
FROM fn_my_permissions('dbName.dbo.tblName', 'OBJECT')
ORDER BY subentity_name, permission_name ;
尽管如此,我实际上被阻止更新该表。这意味着:
- 的输出
fn_my_permissions
不严格正确 - 数据库“只读”设置覆盖单个权限
我了解游戏中的设置是通过以下方式配置的:
ALTER DATABASE dbName SET READ_ONLY
和
ALTER DATABASE dbName SET READ_WRITE WITH NO_WAIT
该问题的主要原因是要了解“只读”配置是 DBA/设计人员在 AG 的设计和部署期间的责任,还是使用 AG 的预期(和保证?)功能。
我会给文档一个很好的阅读。特别是关于可用性副本的部分。
如上所示,每个副本可以是只读的或读写的(分别是辅助或主)。此外,只能有一个主(读写)副本。当我们在这方面提到副本时,我们指的是数据库级别。每个服务器可以托管多个可用性组,可能具有混合的主从配置。
AlwaysOn 可用性组不支持您提到的具有多个读写副本的情况,AlwaysOn 可用性组旨在满足高可用性和读取扩展需求,而不是多主设置。您应该考虑支持这种需求的双向复制技术。
is_read_only
至于只读设置本身,这是由可用性组自动设置的,尽管值得一提的是,这与数据库属性(或 )中的“数据库只读”设置不同sys.databases
,也不是它与文件组级别只读选项的设置相同。我接受了 George 的回答,因为他直接向我指出辅助节点上的状态 AG 数据库将是只读的文档(即通过 MS 的 AG 系统设计)。
然而,在我谈到的问题的最后一个细节中
ALTER DATABASE dbName SET READ_ONLY
,George 澄清说,这与 AG 将辅助节点的角色设置为只读以及该辅助节点上该 AG 中的所有 DB 的含义不同。我对此进行了进一步调查,发现您可以确定由于数据库是辅助节点上的 AG 的一部分而导致更新失败与数据库的只读属性(使用上述 SQL 设置)之间的区别。
下面是一个演示如何
set read_only
和set read_write
影响的脚本sys.databases.is_read_only
- 但更具体地说,它表明如果您尝试更新受此属性保护的数据库,而不是它位于 AG 中的辅助节点上,则会收到一个非常不同的错误消息.以下 SQL 创建了一个新数据库,该数据库将自动进行读写,并且不会成为任何 AG 的一部分,即使是在某个 AG 中充当辅助节点的副本上创建的。
请注意在数据库设置为时尝试更新表时给出错误消息的注释
read_only
- 特别是以下部分:这与原始帖子问题中的错误不同,后者显示
其他地方的一篇文章引用MS Books Online 来阐明此值的目的:
换句话说,错误“无法更新数据库“X”,因为数据库是只读的”可能源于至少两个不同的条件:状态 1 = 数据库属性设置为
read_only
(在 中可见sys.databases.is_read_only
),状态 2 = 的一部分AG 和当前充当辅助节点的副本。