我在一个高交易金融系统中工作。我们有一个表正在同时进行大量事务更新。所有查询都经过优化,数据模型的结构可以灵活支持并发。
我注意到的一个奇怪的事情是,在更新期间,如果我们运行一个在多行上运行 SUM(balance)
函数的查询,AWR 报告显示 57% 的 DB时间花在行锁争用上。
根据我在 Oracle 锁定文档中读到的内容,任何读取都无法获取行上的锁,并且可以安全地读取已提交的数据。是否会出现这样的情况:如果需要成为 SUM
函数一部分的行之一已被 Select for Update
语句锁定,则读取查询将需要等到锁被释放了吗?
如果没有读取查询,事务就能顺利通过,争用率低至 6%。是否有可能读取查询往往是 CPU 密集型的,并由于 CPU 饥饿而导致争用?
我确实注意到,当我们在操作期间运行读取查询时,CPU 平均从 20% 上升到 80%。
最佳答案
好的,首先,您的“读取查询”是SELECT FOR UPDATE
吗?如果是这样,那么,是的这将导致锁定。 SELECT FOR UPDATE
实际上是一个 DML,而不仅仅是一个 SELECT
。它将执行行级锁定,并可能导致争用。
如果您的 SELECT
就是这样,而不是 SELECT FOR UPDATE
,那么它将永远导致行级或被行级阻止锁。
一个相关的想法,虽然你没有提到它,但如果你在繁重的 DML 事件下查询表,你可能会看到查询性能下降,相对于没有发生繁重的 DML 时的查询性能,并且(可能)是由于 Oracle 的读一致性机制,以及 Oracle 可能需要做的额外工作才能获得数据的读一致性 View 。 (将 block 回滚到给定的时间点。)
关于oracle - 可以读取查询导致 Oracle 中的行锁争用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48304762/