删除的 InnoDB 记录回来了吗?

Deleted InnoDB Records Came Back?

TLDR

我大约 8 小时前开始从一个巨大的 InnoDB table 中删除行,当我在 45 分钟前检查时大约有 8000 万行被删除,当我几分钟前刚检查时,计数又回到了什么时候我开始了,但行仍在删除 - 为什么?

问题。 我的团队在几周前继承了一个应用程序,一个可靠的内部应用程序(所以不是 showstopper),它从内部数据源更新报告。最初的开发人员做得很好,但有一个例外 - 当新数据可用时,他没有清理特定 table 中的旧记录,因此随着时间的推移,数据库 table 增长到 500M 记录(每个 bi - 每周更新为此 table) 添加几百万行。

我们决定清理 table (MySql InnoDb) 并向更新脚本添加一些逻辑以防止这种情况再次发生。

第一步:我 运行 一个简单的删除命令需要几个小时,我今天下午开始,打算让它 运行 整晚。我的 SQL 本质上是:

delete from the_enormous_table where batch_id != most_recent_batch_id

大约 45 分钟前,脚本删除了大约 8000 万条记录,但几分钟前我再次检查时,行数似乎已重置为我开始时的位置,但仍在继续删除。

我不是 DBA,但显然以前做过这样的事情 - 从未使用过如此庞大的数据集。我想我从来没有处理过 InnoDB 锁定等的细微差别——或者多年来我已经忘记了它们。

这里有什么问题,我需要将其分解为更小的删除集吗?

如果是这样的话,我可能会用最新的数据集重新创建 table,然后删除旧的 table。

在每个 运行 的开头截断 table;这是丢弃大量数据的更快方法。您可以立即发布 t运行cate,或者删除 table 并根据需要重新创建它,以解决您需要删除 500M 记录的直接问题

对于大DELETEs,有更好的方法。

  • 删除整个table -- TRUNCATE.

  • 替换整个table -- 构建一个新的table,然后使用RENAME.

  • 删除 table 的大部分——使用 PRIMARY KEY 浏览 table 以一次查看 1000 行的块。

  • 定期删除“旧”行 -- PARTITION BY RANGE.

详情:http://mysql.rjweb.org/doc.php/deletebig

(Karwin 的评论解释了标题问题——InnoDB 的行计数反复出现。)