我有一个在单个服务器上具有多个 AG 的环境,它们遇到分裂情况,其中一些最终在一个节点上,而另一些最终在另一个节点上(可能是在故障转移事件中)。当维护任务(重新索引、更新等基本范围)在这些节点上执行时,它们只会在各自 AG 的主端上的 read_write 数据库上有效地执行操作。这会导致作业失败,因为数据库在辅助节点上是只读的。因此,在分裂 AG 的情况下,两个节点都会在作业历史记录中显示维护失败。
不用说,很难监控这些集群。我提出了两种可能的管理解决方案。我们要么根据数据库的可更新性属性使用 DBCC 命令为各个数据库编写维护任务脚本,要么仅将自己限制为每台服务器一个 AG。他们不喜欢这两种解决方案。有谁知道我可以保留内置 SQL Server 维护任务并让它们仅针对主数据库的方法?
SQL Server 维护计划没有内置功能来检测特定数据库的 AG 副本状态并采取相应措施。为此,您必须实现自定义功能。
根据您实施维护任务的方式,有几个选项可供选择。
选项1:
如果您使用 SQL 维护计划,则为每个可用性组创建一组维护计划并仅针对该组中的数据库。删除这些计划的计划,然后创建一个按您想要的计划运行的 SQL 代理作业。让该代理作业检查sys.dm_hadr_availability_replica_states以确认相关 AG 处于主要状态,如果是,则执行相应的代理作业以运行维护计划任务。
选项#2:
如果您使用带有 T-SQL 脚本的 SQL 代理作业来执行维护任务,请在脚本中添加一些逻辑以在执行之前检查sys.dm_hadr_database_replica_states以验证所讨论的数据库确实是主数据库。
选项#3:
重新设计您的维护流程,以利用Ola Hallengren出色的维护解决方案。这具有处理已内置可用性组的逻辑,因此可以节省您自己设计、测试和部署解决方案的时间。您只需部署一组相同的代理作业即可在每个副本上运行存储过程。它们都会执行,但只有您想要执行任何工作的那些才会执行。
笔记:
这些选项中的任何一个都应该以相同的作业部署在所有副本上并同时运行的方式进行部署。唯一的区别是某些任务仅在主副本上执行,而其他任务只是运行作业并由于副本状态而安静地退出,不执行任何工作。
您的管理团队可能不喜欢重构当前维护流程的想法,但现实情况是,如果他们想要自动化处理故障转移,他们必须这样做,否则,维护任务必须在故障转移后手动管理。
我最终为 CheckDB 做了这个。其他任务将简单地使用相同的模板。有用。希望我没有遗漏任何重要的东西。