【发布时间】:2021-05-11 08:01:00
【问题描述】:
我们的生产设置是我们有一个应用程序服务器,其中的应用程序连接到 SQL Server 2016 数据库。在应用服务器上,有几个 IIS 应用程序在 GMSA 帐户下运行。 GMSA 帐户对数据库具有 db_datawriter 和 db_datareader 权限。
我们的团队在同一个 SQL Server 数据库上拥有 db_datareader 权限。我们需要它用于生产支持目的。
我们最近发生了一起事件,团队成员在其本地计算机上调用 SQL Server Management Studio 上的查询:
SELECT * FROM [DatabaseA].[dbo].[TableA] order by CreateDt desc;
TableA有大约 140 万条记录,并且有多个 blob 类型的列。 CreateDt 是 DATETIME2 类型的列。
我们为 SQL Server 数据库服务器配置了 RedGate SQL Monitor。这引发了一个运行了 1738 秒的长时间运行的查询警报。
同时,我们的一个专门向TableA 插入新记录的 Web 应用程序 (.NET 4.6) 经常遇到查询超时错误:
Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
这些错误发生在几乎完全相同的 1738 秒期间。这让我相信这些是相互关联的。
我的理解是SELECT 查询只会创建一个共享锁,不会阻止另一个连接对该表的访问。我的理解是否正确?
我的问题是 db_datareader 对团队成员安全吗?是否存在允许读取数据但绝对无法创建阻止行为的较小权限。
【问题讨论】:
-
This leads me to believe these are connected.连接并完整记录,数百篇文章、课程、书籍解释了它发生的原因以及如何避免这种情况。它从 not 无故查询 1M 行开始。当你读取整个表时,锁会升级到表本身级别,阻塞修改。你想做什么?如果您真的需要读取所有这些行,则可以使用 SNAPSHOT 隔离。这有其自身的成本,因为修改行的版本被复制到tempdb,直到读取事务完成。更好的设计可能更快、更便宜 -
好的,我知道这些肯定是有关联的。答案似乎表明开发人员应该编写他们的查询是避免这种情况的一种特殊方式,这很好。但是,这并不能阻止这种情况的发生(例如意外),是否存在使这种情况变得不可能的特权级别?
-
检查Resolve blocking problems caused by lock escalation in SQL Server 了解为什么锁会升级到页面或表级别以及如何避免这种情况。无论如何,这不是关于特权,而是关于设计。将同一张表用于运营和报告目的是个坏主意,因为报告会读取大量数据,会阻止修改
-
@Ben
to prevent this不要在生产环境中运行临时查询。不要无缘无故给别人datareader。如果人们需要实验或报告,克隆或复制数据。 SQL Server 中的备份操作是在线的,即它们不会阻止应用程序。您可以根据需要进行备份并在不同的服务器上恢复它们。在该服务器上给开发人员datareader,而不是生产数据库
标签: c# sql .net sql-server