改变受 RLS (SSDT) 保护的 MSSQL table
Altering MSSQL table protected by RLS (SSDT)
在 MSSQL 2016 中向受行级别安全性保护的 table 添加新列时,尝试使用 SQL 服务器数据发布数据库时出现以下错误工具:
The current operation will cause data motion on table X. Data motion can not be performed on this table because it has row level security enabled by policy Y. To allow this operation use SqlPackage.exe with option /p:AllowUnsafeRowLevelSecurityDataMovement
我怀疑它想要重新创建 table,如果 RLS 谓词未授予部署用户访问数据的权限,这可能会导致数据丢失。但是我找不到任何关于此的文档。
更重要的是,处理此类部署场景的最佳实践是什么?
这个场景有两个方面:
- 为什么添加列会导致发生数据移动操作?
- 行级安全性带来的危险是什么?
最小化/避免数据移动
一般来说,添加新列应该不需要数据移动。如果添加到 table 定义的末尾,这可以通过 ALTER TABLE ADD COLUMN 操作来完成,并且 SSDT 足够聪明,可以为您完成此操作。但是,如果在 table 中间添加,默认行为是执行完整数据移动,这在大型 table 上可能非常昂贵。为避免这种情况:
- 尽可能将列添加到末尾。
- 如果这不可能,最新版本的 SSDT 和 SqlPackage 有一个
IgnoreColumnOrder
标志,可以将 table 中间的列添加视为添加到末尾。这可能会导致一些复杂情况(例如模式比较也必须设置此设置,否则它会显示 table 的源项目和数据库版本之间的差异),但通常值得这样做以避免部署期间不必要的数据移动
处理行级安全性 (RLS) + 数据移动
如果您确实需要进行导致数据移动的更改,则 RLS 的风险在于您的用户无法访问 table 中的所有行。由于数据移动将数据复制到临时 table,然后删除原始数据并重命名,您将丢失用户看不到的所有行。
解决方案是设置 /p:AllowUnsafeRowLevelSecurityDataMovement
标志,但要验证您的用户不属于任何行级过滤方案。一个好的做法是仅将这些方案应用于权限有限的用户(例如您的应用程序角色),同时在部署时使用具有更大权限的角色(管理员角色)。如果您这样做,您就可以安全部署,但该标志至少可以警告这一点/避免意外数据丢失。
在 MSSQL 2016 中向受行级别安全性保护的 table 添加新列时,尝试使用 SQL 服务器数据发布数据库时出现以下错误工具:
The current operation will cause data motion on table X. Data motion can not be performed on this table because it has row level security enabled by policy Y. To allow this operation use SqlPackage.exe with option /p:AllowUnsafeRowLevelSecurityDataMovement
我怀疑它想要重新创建 table,如果 RLS 谓词未授予部署用户访问数据的权限,这可能会导致数据丢失。但是我找不到任何关于此的文档。
更重要的是,处理此类部署场景的最佳实践是什么?
这个场景有两个方面:
- 为什么添加列会导致发生数据移动操作?
- 行级安全性带来的危险是什么?
最小化/避免数据移动
一般来说,添加新列应该不需要数据移动。如果添加到 table 定义的末尾,这可以通过 ALTER TABLE ADD COLUMN 操作来完成,并且 SSDT 足够聪明,可以为您完成此操作。但是,如果在 table 中间添加,默认行为是执行完整数据移动,这在大型 table 上可能非常昂贵。为避免这种情况:
- 尽可能将列添加到末尾。
- 如果这不可能,最新版本的 SSDT 和 SqlPackage 有一个
IgnoreColumnOrder
标志,可以将 table 中间的列添加视为添加到末尾。这可能会导致一些复杂情况(例如模式比较也必须设置此设置,否则它会显示 table 的源项目和数据库版本之间的差异),但通常值得这样做以避免部署期间不必要的数据移动
处理行级安全性 (RLS) + 数据移动
如果您确实需要进行导致数据移动的更改,则 RLS 的风险在于您的用户无法访问 table 中的所有行。由于数据移动将数据复制到临时 table,然后删除原始数据并重命名,您将丢失用户看不到的所有行。
解决方案是设置 /p:AllowUnsafeRowLevelSecurityDataMovement
标志,但要验证您的用户不属于任何行级过滤方案。一个好的做法是仅将这些方案应用于权限有限的用户(例如您的应用程序角色),同时在部署时使用具有更大权限的角色(管理员角色)。如果您这样做,您就可以安全部署,但该标志至少可以警告这一点/避免意外数据丢失。