Loh*_* MV 7 mysql batch-processing rowlocking
我有一个要求,我们需要在更新时不持有锁的情况下更新行。
以下是需求的详细信息,我们将每 5 分钟在一个表上运行一次批处理,update blogs set is_visible=1 where some conditions该查询将在数百万条记录上运行,因此我们不想在更新期间阻止所有行写入。
我完全理解没有写锁的含义,这对我们来说很好,因为 is_visible 列将仅由该批处理过程更新,其他线程不会更新该列。另一方面,同一个表的其他列会有很多更新,我们不想阻止这些更新
最佳实践是,当更新有可能与其他事务同时发生时,始终获取特定的锁。如果你的存储引擎是MyISAM,那么MySQL将在更新期间锁定整个表,对此你无能为力。如果存储引擎是 InnoDB,那么 MySQL 可能只会在更新目标记录上放置排它 IX 锁,但这种情况有一些注意事项。为了实现这一目标,您要做的第一件事是SELECT ... FOR UPDATE:
SELECT * FROM blogs WHERE <some conditions> FOR UPDATE;
Run Code Online (Sandbox Code Playgroud)
为了确保InnoDB只锁定正在更新的记录,子句中出现的列需要有唯一索引WHERE。在您的查询的情况下,假设id涉及的列,它必须是主键,否则您需要创建一个唯一索引:
CREATE UNIQUE INDEX idx ON blogs (id);
Run Code Online (Sandbox Code Playgroud)
即使使用这样的索引,InnoDB 仍然可以对索引值之间的记录应用间隙REPEATABLE READ锁,以确保契约得到执行。
因此,您可以在子句中涉及的列上添加索引WHERE来优化 InnoDB 上的更新。
| 归档时间: |
|
| 查看次数: |
13998 次 |
| 最近记录: |