使用复制从大表中删除数据

zvi*_*ico 6 mysql replication delete

我需要删除给定表中的所有行。该表包含数百万或记录。主数据库被复制到多个从属数据库,我希望这样做不会造成复制延迟或影响性能。

经过一番研究,我试着放下桌子。这花了很长时间,在此期间我的主数据库被锁定。

我知道我可以分批逐步删除,只是想知道有没有更快的方法。

谢谢,Z

Rol*_*DBA 7

而不是这样做TRUNCATE TABLE(锁定访问表的任何连接),尝试制作表的空副本,将其交换并删除旧表。

例子

假设该表被称为mydb.mytable。像这样做

USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
DROP TABLE mytable_old;
Run Code Online (Sandbox Code Playgroud)

这样做让我们的 mytable 立即变空,并且在删除数据期间不会被锁定。现在,这应该在 Master 上快速运行并且应该复制。最后一行DROP TABLE mytable_old;可能花费的时间最长。如果这与您有关,然后在 Master 和 Slave 上运行它(基于Jynus回答

SET sql_log_bin = 0;
USE mydb
CREATE TABLE mytable_new LIKE mytable;
ALTER TABLE mytable RENAME mytable_old;
ALTER TABLE mytable_new RENAME mytable;
DROP TABLE mytable_old;
SET sql_log_bin = 1;
Run Code Online (Sandbox Code Playgroud)

试一试 !!!

警告

至于小块的删除数据,如果你需要在表数据删除后立即可用的表,这不是一个好主意。为什么 ?

  • DELETE FROM mytable.mytable;是一个单一的事务。所有行都将准备好在 InnoDB 架构中回滚。DELETE 完成后,必须丢弃所有 MVCC 信息。这就解释了为什么需要这么长时间。
  • 以小块删除只会创建更多的事务和更小的回滚。尽管如此,它仍然会创建相同数量的回滚信息和工作。它可以让您监控还有多少数据需要删除。
  • 请不要跑DELETE FROM mydb.mytable LIMIT 1000;LIMITDELETE没有WHERE子句的情况下使用不是复制安全的。


aku*_*sky 5

虽然TRUNCATE TABLE绝对比DELETE FROM我坚持删除小块记录要快。该TRUNCATE TABLE有时可能仍然缓慢,因为很多东西是在幕后去:它抢在字典独占锁,它仍然有删除IBD文件并重新创建一个,它必须从缓冲池中逐出页。使用pt-archiver非常简单。它不会让奴隶滞后,不会有突然的刷新尖峰等,不会膨胀撤消段。