微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在MariaDB / MySQL中没有锁定删除?`(InnoDB)

据我所知,DELETE FROM … WHERE在表上发出锁定.

现在,我在MariaDB中有一个巨大的InnoDB表,其大小为1TB,正在被使用,并且锁定它直到整个数据库搜索到要删除的行是没有选择的.

有没有什么方法可以删除匹配某些条件的行而不会在删除时锁定它?

以下是针对此案例的更多细节:

>服务器正在从Debian Stretch存储库运行MariaDB 10.1.22-3
>服务器有32 GB ram和innodb_buffer_pool_size = 20G
>数据库的大小为1TB,始终有许多活动的INSERT和SELECT
>整个数据库只包含2个表:

>一个表用于实际数据(基本上有一个类似数据的结构(BIGINT id,LONGTEXT数据)(其中数据是JSON的一大块.我知道这不是一个完美的关系数据库模型,但JSON来自一个第三方,它非常复杂,可能随时包含来自第三方的结构变更,恕不另行通知)
>还有一个用于某种“索引”的表来满足SELECT. (简化示例,这可能有像data_index(BIGINT id,INT userId,INT itemId,BIGINT timestamp)这样的结构,所以我可以在userId和itemId上使用SELECT,并加入实际数据.(timestamp是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查询

解决方法:

不,如果不锁定已检查的行,则无法删除.

但是,您可以通过在要搜索的时间戳列上创建索引来最小化检查的行数.

这也将针对您可能尝试在表的末尾插入的潜在行创建gap locks,以确保新行不会影响DELETE.

在InnoDB中,像DELETE创建的普通写锁不会阻止读取.并发事务仍然可以读取行 – 甚至是您要删除的行.

普通的写锁不会锁定整个表.好吧,它使用intention lock锁定表,这只会阻止其他表锁,例如ALTER TABLE或DROP TABLE所需的表锁.换句话说,在进行任何读取或写入操作时,不能对表进行ALTER / DROP操作.

你可能会喜欢我的演讲:InnoDB Locking Explained with Stick Figures.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐