【发布时间】:2017-10-20 19:55:39
【问题描述】:
据我所知,DELETE FROM ... WHERE 在桌子上发出锁。
现在,我在 MariaDB 中有一个巨大的 InnoDB 表,其大小为 1TB+,正在使用中,并且在搜索整个数据库以删除要删除的行之前将其锁定是没有选择的。
有什么方法可以删除符合某些条件的行而不在删除时锁定它?
以下是本案例的更多细节:
- 服务器正在运行来自 Debian Stretch 存储库的 MariaDB 10.1.22-3
- 服务器有 32 GB 内存和
innodb_buffer_pool_size = 20G - 数据库大小为 1TB+,随时都有大量活动的
INSERTs 和SELECTs - 整个数据库只包含2个表:
- 实际数据的一个表(它基本上具有类似
data (BIGINT id, LONGTEXT data)的结构(其中data是一大块JSON。我知道这不是一个完美的关系数据库模型,但JSON 来自第三个方,它非常复杂,并且可能随时包含来自第三方的结构更改,恕不另行通知) - 还有一个表用于某种“索引”以满足
SELECTs。 (简化的例子,这可能有类似data_index (BIGINT id, INT userId, INT itemId, BIGINT timestamp)的结构,所以我可以在userId 和itemId 上使用SELECT,并加入实际数据。(时间戳是unix 时间戳,以毫秒为单位)
- 实际数据的一个表(它基本上具有类似
- 就像我说的,数据只能在有限的时间内存储。所以基本上现在我想创建一个每天运行一次的 cronjob 来删除超过 7 天的行。
为了完成任务,我自然会想出这个简单的查询:
DELETE `data`, `data_index`
FROM `data_index`
LEFT JOIN `data` ON `data`.`id` = `data_index`.`id`
WHERE `timestamp` > (NOW() * 1000) - (7 * 24 * 60 * 60 * 1000)
但这可能会锁定表很长时间。我如何在不锁定表的情况下完成相同的任务,以便数据库对其他SELECT 和INSERT 查询仍然有效?
【问题讨论】:
-
我用了截断,成功了!!