2

我有一个 cron 设置来备份生产 mysql 表,并希望定期从表中清除数据。我必须删除 id 引用的多个表中的数据。

一些背景:我需要删除大约 200 万行,我的应用程序将不断地读取/写入我的数据库(虽然它通常不应该访问被删除的行)

我的问题是我应该如何根据以下参数构建删除查询:

  1. 在单个批量查询中删除与批量删除?
  2. 在单个事务中跨不同表删除与不使用任何事务删除。如果我在事务中使用delete,即使我是批量删除,是否会有任何表级别的锁?
  3. 我没有设置任何分区,碎片会成为问题吗?
4

1 回答 1

0

假设:

  1. 隔离级别:可重复读取——默认 Mysql 隔离级别。
  2. 您拥有的删除查询基于范围而不是主索引。

  3. 删除一个事务中的所有行,将有很长的事务,以及更大的锁。这会增加复制滞后,复制滞后很糟糕,新的 DC 真的很糟糕。拥有更大的锁也会降低您的写入吞吐量。(在隔离级别可序列化的情况下,甚至读取吞吐量也可能会受到影响。)

  4. 批量删除。比全部删除要好,但随着范围的删除,每次删除的锁数会更多,(将采用间隙锁和下一行锁)。所以在范围内批量删除也会有同样的问题,只是更小。

与全部删除和批量删除相比,批量删除更可取。

其他方法:(我们需要在某个时间之前删除行) 1. 有一个守护进程,它运行每个配置时间和。一世。从 purge-time < your-purge-time 的表中选择 pk。-- 没有锁 ii. 删除基于pk,使用多线程。-- 行级锁,小事务(跨表)。

这种方法将确保较小的事务和只有行级别的锁。(基于主键的删除只需要行级锁)。此外,您的查询很简单,因此即使部分删除成功,您也可以重新运行。而且我觉得拥有这些原子不是必需的。

或者

  1. 降低您的隔离级别:即使是 READ_COMMITED,批量删除也应该没问题。在 Read COMMITED 隔离中,即使通过辅助键访问,锁也仅在行上。

或者

  1. 如果您的模型允许基于时间的分片并删除数据库本身:)
于 2015-04-18T10:28:37.620 回答