改变受RLS(SSDT)保护的MSSQL表

时间:2017-10-18 07:32:03

标签: sql-server database deployment sql-server-data-tools row-level-security

在MSSQL 2016中受行级别安全保护的表中添加新列时,尝试使用SQL Server数据工具发布数据库时出现以下错误:

  

当前操作将导致表X上的数据运动。无法在此表上执行数据运动,因为它具有由策略Y启用的行级安全性。要允许此操作,请使用带有选项/ p的SqlPackage.exe:AllowUnsafeRowLevelSecurityDataMovement

我怀疑它想要重新创建表,如果部署用户未被RLS谓词授予对数据的访问权限,则可能导致数据丢失。但是我无法找到任何关于此的文档。

更重要的是,处理此类部署方案的最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

此方案有两个方面:

  • 为什么要添加导致数据运动操作的列?
  • 行级安全性带来的危险是什么?

最小化/避免数据移动

通常,添加新列不应要求数据运动。如果添加到表定义的末尾,则可以通过ALTER TABLE ADD COLUMN操作完成,并且SSDT足够聪明,可以为您执行此操作。但是,如果在表的中间添加,则默认行为是执行完整数据运动,这对于大型表来说可能非常昂贵。为了避免这种情况:

  • 尽可能尝试在最后添加列。
  • 如果无法做到这一点,最新版本的SSDT& SqlPackage有一个IgnoreColumnOrder标志,用于处理表中间的列添加,就像它们被添加到结尾一样。这可能会导致一些复杂情况(例如,模式比较必须具有此设置,或者它会显示源项目和表的数据库版本之间的差异),但通常值得在部署期间避免不必要的数据移动

处理行级安全性(RLS)+数据动作

如果确实需要进行导致数据移动的更改,则RLS的风险在于您的用户无法访问表中的所有行。由于数据运动将数据复制到临时表,然后丢弃原始&如果重命名,您将丢失用户无法看到的任何行。

解决方案是设置/p:AllowUnsafeRowLevelSecurityDataMovement标志,但要验证您的用户不属于任何行级别过滤方案。一个好的做法是仅将这些方案应用于权限有限的用户(例如您的应用程序角色),同时在部署(管理员角色)时使用具有更高权限的角色。如果你这样做,你可以安全地部署,但标志是至少警告这个/避免意外数据丢失。