如何将 DACPAC 部署到事务复制数据库

Posted

技术标签:

【中文标题】如何将 DACPAC 部署到事务复制数据库【英文标题】:How to deploy DACPACs to transaction replicated databases 【发布时间】:2021-09-30 04:06:41 【问题描述】:

我正在通过SqlPackage.exe 将 DACPAC 部署到在 SQL Server 中具有大量事务复制的数据库服务器。 DACPAC 是作为 SQL Server 数据库项目的输出而构建的。当我尝试将 DACPAC 部署到启用了复制的数据库时,SqlPackage 执行返回错误,例如 Error SQL72035: [dbo].[SomeObject] is replicated and cannot be modified.

我找到了参数DoNotAlterReplicatedObjects,它不会在复制打开的情况下改变对象,并且会消除这些错误,这不是我想要做的。相反,我想更改所有对象,而不考虑复制作为部署的一部分。

我能想到的将 DACPAC 部署到这些复制数据库的唯一选择是:

    在部署之前通过脚本删除复制, 通过 SqlPackage 部署 DACPAC, 部署后通过脚本重建复制。

不幸的是,数据库被大量复制,以至于上面的第 3 步需要 7 多个小时才能完成。所以这不是一个实际的解决方案。

有没有更好的方法来使用 SQL Server 数据库项目和 DACPAC 部署到具有大量复制的数据库?

我们将不胜感激。提前感谢您的建议。

【问题讨论】:

这里显而易见的答案是不使用复制的 SQL 数据库。我无法想象依靠自动更新脚本来处理如此重要以至于像这样复制的数据。看来你的欲望有冲突。 DACPAC 部署试图使 PRD 看起来像从其构建位置看的 DEV。您的 DEV 环境中没有启用复制功能吗? 我们在较低的环境中也启用了复制,我们发现在较低的环境中也会出现同样的错误。 这里有一些有希望的答案,但我无法弄清楚他们是否真的解决了它。 dba.stackexchange.com/questions/65568/… 一件事是要非常小心您正在更改的内容 - 不要重新排列列顺序,不要重命名很多对象等。如果您进行非常简单的更改,您不应该很多重建操作。在大多数情况下,添加/删除列和表不应该引起很多问题。您还可以检查生成的脚本,以了解在尝试部署之前会发生什么。 【参考方案1】:

我们通过执行以下操作解决了该问题。希望这也适用于其他人。高级想法是您需要禁用“不更改复制对象”并启用“忽略列顺序”。

有几种方法可以做到这一点。

    如果您在部署管道中使用SqlPackage tool,则使用DoNotAlterReplicatedObjectsIgnoreColumnOrder 属性see this link。所以/p:DoNotAlterReplicatedObjects=False /p:IgnoreColumnOrder=True

    如果您使用 C# 或 PowerShell Dac 类,请使用 DacDeployOptions.DoNotAlterReplicatedObjectsDacDeployOptions.IgnoreColumnOrder 属性。

    您可以直接在 Visual Studio IDE 中修改“高级发布设置”。您取消选中 Do not ALTER replicated objects 复选框并启用 Ignore column order 复选框。请参阅此*** answer,了解忽略复选框的示例。

我们关于为什么这样做的理论是,alter table 只能将列附加到表的末尾,因此将列添加到特定位置的唯一方法是删除并重新创建表。忽略告诉发布者将列附加到末尾,而不管我在脚本中将列放在哪里。

因此,如果您在未指定列列表的情况下执行插入操作,因为您希望列按特定顺序排列而实际上并非如此。

您可能遇到的另一个潜在副作用是 DACPAC 创建的表的列顺序可能与 DACPAC 更改的表不同。我们已经使用这个解决方案几个月了,没有任何问题,但以上是需要注意的事项。

我希望这会有所帮助。

【讨论】:

以上是关于如何将 DACPAC 部署到事务复制数据库的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有实际部署的情况下测试 DACPAC 是不是可以部署

初识MariaDB之5——主从复制原理及部署

部署MySQL Galera Cluster

在 DACPAC 部署中使用 SQL 变量来区分权限

如何从 Dacpac for Azure Pipeline CI/CD 中自动排除仅开发表?

postgresql从库搭建--逻辑复制