我正在运行这样的并发 Postgres 查询:
UPDATE foo SET bar = bar + 1 WHERE baz = 1234
Run Code Online (Sandbox Code Playgroud)
每个查询都会影响固定的 K 行数,我找不到强制执行更新行顺序的方法,最终导致死锁。目前我通过手动执行订单来解决这个问题,但这意味着我必须执行比平时更多的查询,同时还将搜索复杂度从 O(log N + K) 提高到 O(K log N)。
有没有办法提高性能而不会最终容易陷入死锁?我怀疑如果Postgres 以扫描它们的相同顺序更新行,用(baz)索引替换(baz, id)索引可能会起作用,这是一种值得追求的方法吗?
我读到,如果我使用 IsolationLevel.ReadUncommitted,则查询不应发出任何锁。但是,当我对此进行测试时,我看到了以下锁定:
Resource_Type:HOBT
Request_Mode:S(共享)
什么是 HOBT 锁?与 HBT(堆或二叉树锁)相关的东西?
为什么我还会得到 S 锁?
在不打开隔离级别快照选项的情况下进行查询时如何避免共享锁定?
我正在 SQLServer 2008 上对此进行测试,并且快照选项设置为关闭。查询仅执行选择。
我可以看到 Sch-S 是必需的,尽管 SQL Server 似乎没有在我的锁定查询中显示它。为什么它仍然发出共享锁?根据:
在该
READ UNCOMMITTED级别运行的事务不会发出共享锁,以防止其他事务修改当前事务读取的数据。
所以我有点困惑。
我们运行 SQL Server 2000,每天晚上都会遇到一些这样的错误。
Could not continue scan with NOLOCK due to data movement
Run Code Online (Sandbox Code Playgroud)
引发此错误的查询是一个大型复杂查询,它连接了十多个表。我们的基础数据可以经常更新。
文化“最佳实践”是,在过去,NOLOCK提示的引入提高了性能并改进了并发性。这个查询不需要 100% 准确,即我们会容忍脏读等。然而,我们正在努力理解为什么数据库会抛出这个错误,即使我们有所有这些锁定提示。
任何人都可以对此有所了解 - 温柔一点,我实际上是一名程序员,而不是 DBA :)
PS:我们已经应用了前面提到的修复:http : //support.microsoft.com/kb/815008
我有两个存储过程在系统负载时会死锁。Proc A 正在从一个表中选择,而 Proc B 正在插入同一个表中。锁图显示 Proc A 有一个 S 模式页锁,而 Proc B 想要一个 IX 模式锁,但是 Proc A 正在等待另一个页面的 S 模式页锁,而 Proc B 已经有一个 IX 模式页锁.
显然,这可以通过确保两个查询以相同的顺序锁定表中的页面来解决,但我不知道如何做到这一点。
我的问题是:在执行 INSERT 和 SELECT 时,SQL Server 如何确定锁定页面的顺序以及如何修改此行为?
将客户的数据库移动到额外的服务器后,我们遇到了问题。这应该会对站点的性能产生积极的影响,但是 MyISAM 中的表锁定存在问题。(我听说过使用 InnoDB 代替 MyISAM,但我们不能在不久的将来更改引擎)。
我们可以发现它是一个更新查询,当主持人在文章站点上激活评论时执行该查询。这是过程:
SET status = 1 WHERE id = 5(设置索引)此时整个页面变得缓慢。数据库本身忙了几分钟。我取了几次进程列表,看到大约 60 个不同选择查询的条目,它们都处于等待表级锁定的状态。
1.我不明白为什么表上的这个更新article_comments会影响表的选择语句article以等待表级锁。在 processlist 中,几乎所有等待的查询都来自该表。我已经读过更新/插入比选择更受欢迎的事实,这可能会导致此类问题,但是当评论被激活时,文章表本身不会更新,因此选择不应该等待。我误解了吗?
2. 除了更改为 InnoDB 之外,还有什么可以防止这种行为或至少是为了获得更好的平衡吗?我对在将数据库移动到新服务器之前没有出现这个问题感到非常恼火。我想有一些配置错误,但我不知道如何识别。
此处找到的 SQL Server 中的隔离级别列表指出,在事务中获取的写锁将保留到事务结束。但是,它没有提及有关何时获取这些锁的任何信息。
默认情况下,锁是在事务开始时获取还是在需要时获取?如果后者为真,那么在大型事务中尽可能晚地执行写操作以最小化持有 X 锁的时间是否有利?
我一直在对 MSSQL Server 和 Oracle 中的锁定/阻塞进行一些测试,我注意到一个区别:
在 Oracle 中 - 我在不发出提交或回滚的情况下对一行执行更新,在另一个会话中我可以查看底层记录,当然,我可以查看最后提交的数据,而不是尚未提交的值。
在 MSSQL Server 中 - 当我在另一个会话中执行相同的操作时,SQL Server 一直在等待正在更新的行的提交或回滚。
有人可以解释一下 MSSQL 服务器和 Oracle 之间的锁定机制。
所述的PostgreSQL 9.4文档指出添加NOWAIT选项将SELECT FOR UPDATE当行不能被锁定时产生一个错误的装置:
要防止操作等待其他事务提交,请使用 NOWAIT 选项。使用 NOWAIT,如果无法立即锁定所选行,该语句将报告错误,而不是等待。
那究竟是什么错误?
由于这是一个可接受的条件,我希望我的 Java 代码检查此类预期错误,然后解决它。
编辑:为什么会话报告被阻止但等待PAGELATCH_*,而不是LCK_M_相关的等待类型?
我之前假设 SQL Server 只会在 blocks_session_Id 列中报告阻塞会话。如果被阻塞的会话正在等待逻辑锁而不是其他任何东西,例如PAGELATCH_*.
早上/下午/晚上好。
我试图在有几百万行的表中添加一列。这是完整的查询:
alter table date_tasks_mark add column noDuplicate int unsigned not null default 0
Run Code Online (Sandbox Code Playgroud)
不过好像卡住了。
| 28893 | root | localhost | database_name | Query | 10668 | Waiting for table metadata lock | alter table date_tasks_marks add column noDuplicate int unsigned not null default 0
Run Code Online (Sandbox Code Playgroud)
终止查询对我来说安全还是会破坏我的表(它已经处于这种状态大约半小时)?
locking ×10
sql-server ×5
deadlock ×4
mysql ×2
postgresql ×2
blocking ×1
innodb ×1
myisam ×1
mysql-5.5 ×1
mysql-5.6 ×1
nolock ×1
optimization ×1
oracle ×1
performance ×1
select ×1
transaction ×1
update ×1
wait-types ×1