在 Azure DevOps Release Pipeline 中如何在部署期间有条件地停止 SQL 复制

43次阅读
没有评论

问题描述

在使用 Azure DevOps Release Pipeline 部署数据库时遇到了一个问题。他们使用 dacpac 文件来部署/更新 MS SQL Server 数据库。该数据库是复制的,当 dacpac 文件包含对任何表的修改时,他们需要在继续部署之前手动终止复制。部署完成后,他们运行一个脚本来重新开始复制。另一方面,如果只有存储过程被修改,复制可以在部署期间继续进行。
用户觉得这种手动干预很麻烦,想知道是否有人已经在 Azure DevOps Release Pipeline 中解决了这个问题。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

在 Azure DevOps Release Pipeline 中,可以通过以下步骤解决这个问题:
1. 创建一个 Command Line 任务,执行 SqlPackage.exe /Action:DeployReport /p:DoNotAlterReplicatedObjects=false ... 命令。这将创建一个包含有关部署将更改的表等信息的 XML 文件。重要的是要注意,DoNotAlterReplicatedObjects 参数应设置为 false,否则 SqlPackage 将失败。
2. 在 Azure Release Pipeline 中的第二个任务中,使用 Powershell 和 XPath 分析生成的 DeployReport(即 XML 文件)。Powershell 任务将创建一个布尔类型的输出变量,指示是否需要停止复制。在用户的情况下,他分析 XML 文件,如果创建/修改/删除了表,则停止复制。设置输出变量的语法如下:

Write-Host "##vso[task.setvariable variable=haltReplication;isOutput=true]$haltReplication"
  1. 第三步是另一个 Powershell 脚本,用于停止复制。这个脚本只会在 $haltReplication 评估为 true 时运行。在控制选项中,自定义条件为 and(succeeded(), eq(variables['haltReplication.haltReplication'],'1'))

    注意:SqlPackage.exe 生成的 XML 文件包含命名空间,这使得使用 XPath 有些麻烦。以下这个 Stack Overflow 的回答对我帮助很大:https://stackoverflow.com/questions/36417189/ignore-namespace-in-xpath-as-this-can-be-dynamic?rq=1

方案2

使用 SqlPackage.exe /action;deployreport 命令可以获取差异并检查结果,但需要将差异写入磁盘文件。
另一种方法是使用 SqlPackage.exe 的 /action:deployreport 命令来获取差异,并将结果写入磁盘文件。然后,你可以手动检查文件以确定是否需要停止复制。
以下是使用 SqlPackage.exe 的步骤:
1. 执行 SqlPackage.exe /action:deployreport /p:DoNotAlterReplicatedObjects=false ... 命令,将差异信息写入磁盘文件。
2. 打开生成的差异文件,检查其中的表修改情况。
3. 如果差异文件中有表被创建/修改/删除,那么需要停止复制。
请注意,这种方法需要手动检查差异文件,并根据需要停止复制。
以上是两种解决方案,你可以根据自己的需求选择适合的方法来解决这个问题。

正文完