pt-archvier也是pt-toolkit工具箱的一员,可以用于历史数据归档,以及过期数据清理等场景。
工作流
根据使用场景,可以分成以下3中方式:
1、归档数据
源端读取数据------> 保存到目标端-------> 源端数据删除。
2、拷贝数据,异地存储,源端不删除
源端读取数据------> 保存到目标端。
通过参数设置(–no-delete)
3、直接源端删除,不拷贝数据
源端读取数据------>进行删除。
通过参数(–purge,不带–dest和–file)
工具特点
优点:
1、分布式事务控制
提供了简易的分布式事务控制,对于归档需求,保证了目标端insert和源端delete的事务一致性。
2、批次控制
官方说明里的词叫nibbles(一口一口的咬),提供了分批次处理的方式,各小批次之间可以sleep,保证归档事务的大小可控。
3、输出方式多样
支持归档到数据库和文件两种方式,两种方式也可以同时使用。
缺点:
1、参数太多,学习测试成本还是有的。
2、部分场景虽然可以实现,但是不是最优方案。
pt-archiver默认情况下,按照主键顺序查询数据(按照primary-key-only方式)
select id from force index (primary) table_name where modify_time < ‘xxxxx’ order by id limit 200;
操作会强制走primary索引,删除操作也会走primary索引。
而我们的删除操作没必要前置按照order顺序进行删除,应该是直接走modify_time的索引是最优的执行方案。
如果使用–no-ascend参数。
查询阶段会没有force index 和order by id
但是delete阶段仍然会 delete from table_name where id >= xxxx and id < yyyy and modify_time < ‘zzzz’ limit 200
会走primary索引,显然也不对,应该走modify_time索引。
因此pt-archiver方式效率不太好。
参数介绍
安装完成后,可以使用以下命令查看相关文档,以下的内容也主要是翻译自这个文档。
## 详细说明
perldoc /bin/pt-archiver
## 简化版
pt-archiver --help
参数冲突说明
至少指定"--dest", "--file", or "--purge" 参数中的一个。
"--ignore" 和 "--replace" 不兼容.
"--txn-size" 和 "--commit-each" 不兼容.
"--low-priority-insert" 和 "--delayed-insert" 不兼容.
"--share-lock" 和 "--for-update" 不兼容.
"--analyze" 和 "--optimize" 不兼容.
"--no-ascend" 和 "--no-delete" 不兼容.
如果指定COPY项,则"--dest"选项默认和"--source"的值一样。
这个COPY项,没有测试怎么使用。不太用得到。
基础参数
--source 指定源端数据库,采用DSN格式,怎么写不说了,很简单
--ask-pass 提示输入数据库密码
# 以下三种方式可以任选其一,dest和file可以同时使用。
--dest 导出到数据库
--file 导出到文件
--purge 不导出,直接在源端删除数据
# 归档条件
--where 指定归档条件,可以使用子查询。
# 字符集设置
--charset
# 测试使用,不会执行任何操作,但会打印sql
--dry-run 测试使用
优化输出显示
--statistics 显示统计信息,比如执行时间,处理行数等
--progress 指定处理多少行后打印一次处理进度信息
--why-quit 显示脚本退出原因
## 以上三个参数强烈建议都加上。
--quite 安静模式,强烈不建议用。
处理过程优化
## 批次设置
--limit 批次大小,以row为单位,默认为1
--sleep 各批次处理之间sleep的时间。
--sleep-coef 按照百分比定义sleep时间,比如上一批次处理了10s,如果sleep-coef定义为40%,则sleep时间为10 * 0.4 = 4s。
## 提交设置
--commit-each 逐行提交。默认值。
--txn-size 设置事务大小,按照行数算,比如一个begin;commit之间有10个insert语句。
## 批量操作
--bulk-delete 不再每行生成一个delete语句(id=),而是一个chunk生成一个delete语句(id > and <=).
--bulk-delete-limit
--bulk-insert 不再每行生成一个insert语句,而是一个chunk生成临时文件,采用load data方式导入。
## select阶段
--for-update 在选取(select)批次数据时,使用for update.
--share-lock 在选取(select)批次数据时,使用share-lock.
## insert阶段
--ignore 在插入数据时,使用insert ignore,忽略报错。
--replace 在插入数据时,使用replace into代替insert into。
输出到文件相关
--output-format dump或者csv,就是列分隔符不一样,csv以逗号分隔,dump文件以tab分隔
--header 文件如不存在则输出时打印文件头的列信息,如果文件已存在,则不打印header。
数据库优化
--optimize 在归档结束后,在源端或者目标端执行optimize操作。
--analyze 在归档结束后,在源端或者目标端执行analyze操作。
--local 设置执行的optimize或者analyze操作不计入binlog日志。
对MyIsam的优化项
--high-priority-select
--low-priority-insert
--low-priority-delete
--delayed-insert
--quick-delete
参考:http://blog.chinaunix.net/uid-9950859-id-163564.html
1、以上优先级调整的语句都是针对最小表级别锁粒度的存储引擎来说的,比如MyISAM.
2、MyISAM有默认的语句调度策略:
- 写入操作优先于读取操作。
- 对某张数据表的写入操作某一时刻只能发生一次,写入请求按照它们到达的次序来处理。
- 对某张数据表的多个读取操作可以同时地进行
3、以上high-priority、low-priority、delayed都是用来调整这个默认的调度策略的。
举例说明
1、归档场景推荐设置
1、200条一个批次
2、每批次之间sleep 处理时间的50%时间。
3、使用批量插入和批量删除。
4、同时归档到文件和归档数据库。
5、每10W条打印一次处理进度信息
pt-archiver --source h=xxx,P=3306,u=root,D=wjf,t=wjf_test_archiver,A=utf8 --dest h=dddd,P=3306,u=root,D=wjf_archive,t=wjf_test_archiver,A=utf8 --ask-pass --file=‘/tmp/wjf_test_archiver.dmp’ --header --charset=utf8 --where "created < '2021-03-01'" --limit 200 --sleep-coef 0.5 --bulk-insert --progress 100000 --statistics --why-quit
2、清理过期数据推荐设置
pt-archiver --source h=xxx,P=3306,u=root,D=wjf,t=wjf_test_archiver,A=utf8 --ask-pass --purge --primary-key-only --where "created < '2021-03-01'" --limit 200 --sleep-coef 0.5 --progress 100000 --statistics --why-quit
3、只转储到文件csv,不进行删除
pt-archiver --source h=xxx,P=3306,u=root,D=wjf,t=wjf_test_archiver,A=utf8 --ask-pass --file=‘/tmp/wjf_test_archiver.dmp’ --header --output-format csv --charset=utf8 --where "created < '2021-03-01'" --limit 200 --sleep-coef 0.5 --progress 100000 --statistics --why-quit --no-delete
4、其他
参数众多,其他场景根据需求调整参数即可。
未解决问题
## 以下两个参数什么意思,有什么影响
--[no]safe-auto-increment
--run-time
### sentinel和stop有什么区别
--sentinel
--stop
## 怀疑影响select 部分的oder by子句,但是ascend-first测试下来不对
--ascend-first
--no-ascend