从mysql表中清除数据

时间:2015-04-17 14:21:46

标签: mysql archive purge

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

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

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

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

1 个答案:

答案 0 :(得分:0)

假设:

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

  3. 删除一个事务中的所有行,  将有非常长的事务,以及更大的锁。这会增加复制延迟,复制延迟很差,新的DC会让它变得非常糟糕。拥有更大的锁也会降低写入吞吐量。 (如果是隔离级别Serializable,甚至读取吞吐量也可能会受到影响。)

  4. 批量删除。 比删除all更好,但是当范围发生删除时,每次删除的锁数会更多,(将采用间隙锁和下一行锁)。因此,批量范围内的删除也会有相同的问题。

  5. 与全部和批量删除相比,最好是批量执行。

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

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

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

      1. 如果您的模型允许基于时间的分片并删除db本身:)