AlwaysOn DDL 和架构更改

2 sql-server availability-groups

任何人都可以讨论如何逐步将 DDL 架构更改与 Always On Availability Groups 准确合并?我们在一个状态有一个主副本,在另一个状态位置有一个辅助副本。辅助副本将是只读异步的。

如果我要进行架构更改,包括任何种类...

例子

  1. 添加/修改/删除表上的列
  2. 添加/修改/删除表外键约束
  3. 添加/修改/删除聚集和非聚集索引
  4. 添加/修改/删除默认约束
  5. 添加/修改/删除存储过程和函数
  6. 添加/修改/删除触发器
  7. 添加/修改/删除视图

... 我需要什么才能确保主副本 DDL 顺利流向次副本?

我的假设

次要副本上的读取查询不会影响主 DML(数据修改、插入、更新、删除),并且会顺利进行,因为次要副本设置为读取快照隔离。

次要副本上的读取查询会影响主 DDL(模式更改、表结构更改),因为读取查询会放置模式锁。

解决方案

停止对从副本的所有查询,进行主副本DDL,然后DDL变化会流向从副本。

  • 在此过程中是否还需要其他任何步骤?
  • 还有什么需要认真做的?
  • 关闭辅助副本上的所有读取查询的最佳方法是什么?杀死/关闭 Spid,立即使用回滚设置 SINGLE_USER?

此示例仅用于辅助只读异步。如果辅助副本是只读同步的怎么办?


其他背景:Primary Replica是OLTP,日夜事务。我们公司有一个部署变更管理时间窗口。假设我早上只有 1 小时来执行架构和 DDL 更改。我不能等待长时间的查询完成。在异步模式下,日志重做永远不会是最新的。

我记得读过 Microsoft 文章Active Secondary:Readable Secondary Replicas (Always On Availability Groups)

Rem*_*anu 9

为 AlwaysOn 日志流提供服务的重做线程将阻止尝试获取所需的SCH-M锁(SCH-M对于您引用的任何情况,它是什么DDL都没有区别)。

对引用锁定对象的辅助节点的新查询将合并在等待SCH-M锁后面(它们不能偷偷摸摸地前进,以防止服务员饿死)。最终,持有 的最后一个查询SCH-S将耗尽并解除重做线程的阻塞。重做线程将获得锁并恢复,应用日志记录。

当 DDL 提交的日志记录将被重放时,锁将被释放,辅助查询将恢复。所有这些也在AlwaysON – HADRON 学习系列:lock_redo_blocked/redo worker Blocked on Secondary Replica 中进行了描述

Sync 或 Async AlwaysOn 没有区别,因为同步部分适用于接收到的日志持久性,而不是重放(重做)接收到的日志。

通常不需要停止对辅助节点的查询。所描述的机制将处理这种情况。在极少数情况下,您的辅助查询可能会持续很长时间(+30 分钟)并且可能会阻塞日志重做,您应该监控阻塞情况并可能采取措施。


您需要确保日志重做是最新的(即收到的日志和待重做的日志不多),但这是正常状态。然后只需应用 DDL。如果您注意到辅助节点上的重做阻塞,您可以终止阻塞重做的单个 SPID。注意:我说“重做是最新的”的原因只是为了在事情发生时进行控制。如果重做晚了 30 分钟,那么您现在应用 DDL,它将在 30 分钟后重播,因此现在杀死辅助查询是没有用的。并不是说您必须完全保持最新状态,小延迟(重做队列大小)应该没有害处。

在异步模式下,日志重做可以获得当前。这完全取决于主要写作的速度。想一想,如果主节点在 1 小时内没有写入,从节点会拒绝应用收到的最后一个日志吗?