先交代一句:这篇东西不是纸上谈兵,是我在好几套生产环境里真刀真枪用出来的。如果你手头有张 MySQL 表,已经跑到几亿行,每次 DELETE 一下历史数据就锁表、慢查询报警、主从延迟飙升,那你大概率需要认识一下 pt-archiver 这个工具。它是 Percona Toolkit 里的老牌成员,专门解决“在线清理和归档 MySQL 大表数据”这个痛点。写这篇文章,是想把 pt-archiver 从安装、参数理解、实战命令到自动化调度一次讲透,给正在被大表膨胀折磨的 DBA、后端开发、运维朋友一条能直接照做的路子。
我最早接触这个工具也是被逼的:一张订单流水表 3 亿多行,磁盘快满了,业务还不能停,用传统 DELETE 删数据删到晚上,主库直接扛不住。后来用 pt-archiver 做分批归档加删除,才把数据库从生死线上拉回来。下面所有内容,都是围绕“怎么安全地把大表里的历史数据挪走”这个核心展开的,你不需要有很深的MySQL基础,只要会跑命令行,按顺序看完就能上手。
1. 为什么清理大表数据非它不可
1.1 传统 DELETE 在大表场景下的致命伤
很多人的第一反应是:清理数据不就是 DELETE FROM table WHERE create_time < '2022-01-01' 吗?这句话在几百万行的小表上没错,但到了几亿行的表上,就是事故现场。
普通 DELETE 在执行时,InnoDB 要把满足条件的行逐条标记删除,同时记录到 undo log 和 redo log,而且这整个过程是在一个大事务里完成的。也就是说,在语句执行期间,这几十万、几百万行数据一直被锁住,其他业务的 SELECT、UPDATE 只能排队等。你还会看到另一个问题:主库上一个大 DELETE 运行 20 分钟,从库为了追主库的 binlog,要连续执行 20 分钟的单线程回放,主从延迟瞬间拉到几分钟甚至更久。
还有个容易被忽略的坑:按 create_time 这种普通索引条件去 DELETE,没有主键顺序的约束,InnoDB 删除的时候是随机扫描二级索引再回表,每删一批 IO 都很差,删到一半系统负载就上去了。更别提大事务回滚时的灾难——如果 DELETE 没执行完被你手动 kill,MySQL 需要回滚整个事务,这个回滚比删除还慢,等于数据库当场“罢工”。我在生产环境见过一次误操作,一个 delete 共影响 2000 万行,跑了 25 分钟后发现条件写错想取消,回滚用了将近 1 小时,这期间那台主库的其他查询全部超时。
1.2 pt-archiver 的核心思路:小事务、分批、可暂停
pt-archiver 解决这个问题的思路特别清晰。它不会一次性锁住所有满足条件的行,而是顺着表的主键或者唯一索引,用高效的范围查询一次只取一小批数据,比如默认一次 400 行,处理完这一批就提交一个事务。然后继续往下跑,直到把所有满足条件的行都处理完。
这样做有几个实打实的好处:
- 锁粒度极小。每个事务只涉及几百行,别的事务在该表上的插入、更新基本不受影响,只有在处理到特定主键范围时会短时间持有行锁。
- 主从延迟可控。每处理一批之后可以 sleep 若干秒,给从库留出追 binlog 的时间,让延迟保持在一个安全水位。
- 可以随时中断。因为是分批提交,你随时 Ctrl+C 杀掉进程,已经提交的事务会保留,没跑的不会产生大回滚,下次再跑还能接着来。
我经常打一个比方:传统 DELETE 像是用挖掘机在小区里拆楼,轰隆一下全砸了,动静大还震坏周边的邻居;而 pt-archiver 像一支装修队,按楼层一间一间拆,拆完一间运走一间,虽然工期长一点,但全楼的人照常生活。这个特质,决定了它天生就是为“线上大表清理”这个场景设计的。
另外它还自带一个很关键的“归档”能力,不光是删,还能在删除的同时把数据写到文件、或者插入到另一张历史表。这样你的数据不会真的消失,只是从“热表”挪到了“冷库”,审计、数据分析、合规留档的需求全都照顾到了。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 安装与参数体系,动手前的必修课
2.1 Percona Toolkit 的安装和验证
pt-archiver 是 Percona Toolkit 中的一个工具,不是 MySQL 自带的,所以先要装这个工具包。不同操作系统安装方式略有差异,我常用的两种:
Debian/Ubuntu 系:
bash复制wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
apt-get update
apt-get install percona-toolkit
CentOS/RHEL 系:
bash复制yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
yum install percona-toolkit
macOS 上做开发测试的话可以直接 brew install percona-toolkit。装完之后用 pt-archiver --version 验证一下,能看到类似 pt-archiver 3.5.5 的输出就说明环境就绪。
这里插一句,Percona Toolkit 是一整套 MySQL 运维工具集,除了 pt-archiver,还有常用的 pt-query-digest、pt-online-schema-change、pt-table-checksum 等等。你只装一个包,等于这些工具都备齐了,后面做数据库巡检、大表 DDL 变更都用得上。
2.2 核心参数速查,每个参数都别乱用
pt-archiver 的参数非常多,但日常归档根本用不着全部,记住下面这些就够了。我按功能分了几组,方便你对照排查。
表连接与认证:
- --host、--port、--user、--password:连接数据库的基础信息。注意密码不要直接写在命令行里,可以用 --ask-pass 手动输入,或者写到 ~/.my.cnf,避免密码泄露到 shell history。
- --socket:走本地 socket 连接时使用,效率更高。
核心归档条件:
- --source:必填,指定要操作的源表,格式是 D=库名,t=表名。
- --dest:选填,指定归档目标表,格式一样。如果不指定,就只把数据导出到文件或者直接删除。
- --where:必填,归档条件,相当于 SELECT 的 WHERE 子句,决定你要把哪些行挪走。这个条件非常关键,必须能用到索引,否则性能会打折扣。
- --limit:每个批次取多少行,默认是 400。调大这个值可以提高吞吐,但会增加单批锁范围,生产环境建议 500~2000 之间做取舍。
- --txn-size:每个事务处理多少行,默认是 1。注意这个参数和 --limit 是配合的,也就是说 --tx
