我尝试了一个alter table X add column C
,但它花费了太长的时间并回滚了(实际上杀死了它)。当我这样做时,sp_who2 显示 DiskIO = 5 百万。
假设无论时间如何,还需要 500 万才能完成回滚,这有意义吗?如果不是,是否有某种与事务日志有关的乘数?
我尝试了一个alter table X add column C
,但它花费了太长的时间并回滚了(实际上杀死了它)。当我这样做时,sp_who2 显示 DiskIO = 5 百万。
假设无论时间如何,还需要 500 万才能完成回滚,这有意义吗?如果不是,是否有某种与事务日志有关的乘数?
我以 sa 身份登录(在我的会话中使用 select suser_name() 仔细检查了它)。
我cards_login_generator
在数据库 [cards] 上创建了一个登录名和同名用户。我想允许该用户创建登录名、用户,并使他们成为db_datareader
和的成员db_datawriter
。
我已经同意ALTER ANY LOGIN/USER
并且它有效。现在是时候了:
grant alter on role::[db_datareader] to cards_login_generator
失败了:
找不到角色“dbo.db_datareader”,因为它不存在或您没有权限。
我已经彻底搜索过,但无法想象此消息的任何原因。该角色是一个(可能是不可删除的?)数据库角色,我是 sa,所以不会出现权限问题。为什么会失败?
Microsoft SQL Server 2017 (RTM-GDR) (KB5014354) - 14.0.2042.3 (X64)
当我有一个包含多个查询的事务时,我可以通过使用waitfor
和检查dm_tran_locks
.
但我不能将一个查询“暂停”一半。具体来说,我想知道这个查询将如何持有锁:
update my_table set column1=new_value
where column2=filter_value
这会从一开始就需要更新锁定吗?或者它会在确定指定的行之前使用共享锁where
,然后请求 U 锁?
我试图弄清僵局。有问题的表mytb
仅用于以下查询:
delete mytb with (uplock,holdlock) where key_value=@value
通过 sp_executesql 调用。后面提到的两个进程都使用相同的代码,除了键值。
我正在使用跟踪标志 1222,这是服务器日志中的资源列表部分:
resource-list
objectlock lockPartition=0 objid=1433553235 subresource=FULL dbid=16 objectname=mydb.dbo.mytb id=lock5620a3480 mode=IX associatedObjectId=1433553235
owner-list
owner id=process4bd94c8 mode=IX
waiter-list
waiter id=process4c85288 mode=X requestType=convert
objectlock lockPartition=0 objid=1433553235 subresource=FULL dbid=16 objectname=mydb.dbo.mytb id=lock5620a3480 mode=IX associatedObjectId=1433553235
owner-list
owner id=process4c85288 mode=IX
waiter-list
waiter id=process4bd94c8 mode=X requestType=convert
我的理解如下:两个进程(让我们从它们的最后两个 id 字符中称它们为“c8”和“88”)设法在表上获得相同的 IX 锁,然后尝试变成 X 锁以删除必要的行,但一个进程阻塞了另一个进程。
我的理解正确吗?如果是,为什么进程共享 IX 锁?系统是否不应该拒绝访问 IX 锁来限制竞争条件的进程,这将导致第一个进程首先完成,然后第二个进程可以开始?
发表评论补充:在挖掘更多时,我发现where
条件上的索引不存在,而我希望它是聚集的主键。没有这个索引会不会是死锁的原因?
在调试死锁时,我注意到在 xml 中resource-list
,第一个和第三个对象锁是相同的。这有什么原因吗?
<resource-list>
逐字逐句:
<resource-list>
<objectlock lockPartition="0" objid="580509447" subresource="FULL" dbid="7" objectname="censoredV2.dbo.pt_sales" id="lock1929b2d5500" mode="Sch-M" associatedObjectId="580509447">
<owner-list>
<owner id="process194df0e5468" mode="Sch-M" />
</owner-list>
<waiter-list>
<waiter id="process1947a066ca8" mode="Sch-M" requestType="wait" />
</waiter-list>
</objectlock>
<objectlock lockPartition="0" objid="94623380" subresource="FULL" dbid="7" objectname="censoredV2.dbo.pt" id="lock1929a8cf480" mode="IX" associatedObjectId="94623380">
<owner-list>
<owner id="process1907da684e8" mode="IX" />
</owner-list>
<waiter-list>
<waiter id="process194df0e5468" mode="Sch-M" requestType="wait" />
</waiter-list>
</objectlock>
<objectlock lockPartition="0" objid="580509447" subresource="FULL" dbid="7" objectname="censoredV2.dbo.pt_sales" id="lock1929b2d5500" mode="Sch-M" associatedObjectId="580509447">
<owner-list>
<owner id="process1947a066ca8" mode="Sch-M" requestType="wait" />
</owner-list>
<waiter-list>
<waiter id="process1907da684e8" mode="IX" requestType="wait" />
</waiter-list>
</objectlock>
</resource-list>
我被分配研究列级加密,附加要求sa
是无法读取加密列。
我在这篇 DBSE 帖子中读到的想法是创建一个受密码保护的证书,下面是一堆对称密钥,客户端应该使用只有他们知道的密码打开这些密钥。
这似乎可以确保除了客户端之外没有其他人可以读取加密数据。但是,他们仍然可以修改它们(删除它们或更新=损坏它们)。据我了解, usingENC/DECRYPTBYKEY
只是一个标量函数,与表无关。这意味着是否有人在特定列上使用这些函数不会“通知”数据库这些列包含加密数据。因此,“保护”数据的唯一方法是老式的特权方法。
我错过了什么吗?有没有办法限制列仅在打开特定键时接受更新或删除?甚至,在更新的情况下,要求该inserted.
值始终是 EncryptByKey 函数的输出?
对于 role db_denycustomer
,我只希望customer 表的列代码是 SELECTable,而其他的都不是。所以我这样做了:
DENY SELECT ON dbo.customer TO db_denycustomer
GRANT SELECT ON dbo.customer (code) TO db_denycustomer
...而且效果很好。凉爽的!但是,为什么?
我在相关文章中读到的是权限堆栈,但DENY
优先。相反,在我的例子中,似乎最后一个权限“查询”优先。果然,如果我倒序执行,后者DENY
也隐藏了代码栏。
你能详细说明一下吗?
我还包括了我测试过的用户的默认值db_datawriter
和角色。db_datareader