概述
官方文档:https://www.percona.com/doc/percona-toolkit/LATEST/pt-archiver.html
将MySQL表中的数据归档到另一个表或文件中。
- 需要表有主键
- 默认迁移完成是会删除源表数据的。
- 从一张表导入到另外一张表,要注意的是新表必须是已经建立好的一样的表结构,不会自动创建表,而且where条件是必须指定的
- 不会自动执行analyze和optimize,有需要可以在迁移完成后低峰期执行
-
注意:
若没有加上参数--no-safe-auto-increment
导出和删除都会少掉最后一条记录(最大的ID值),这个是由于8.0之前重启会根据最大值设定auto-increment,pt放在最大的序列变化而不变更最后一条 - 若归档过程中,源数据被变更了,可能出现数据不一致,例如id为3的数据,在执行归档时已读取过这部分值,在归档过程中源又被修改了值,那么这个被修改的值是不会被记录到归档表中去的。
可使用
--for-update
或--share-lock
对读取数据锁定不允许修改。但会影响源数据业务。
安装
# 安装依赖
yum install perl-DBI perl-DBD-MySQL perl-Digest-MD5 perl-IO-Socket-SSL perl-TermReadKey
# 下载rpm包
wget https://www.percona.com/downloads/percona-toolkit/3.2.0/binary/redhat/7/x86_64/percona-toolkit-3.2.0-1.el7.x86_64.rpm
# 安装
rpm -ivh percona-toolkit-3.2.0-1.el7.x86_64.rpm
官方下载地址:https://www.percona.com/downloads/percona-toolkit/LATEST/
语法
pt-archiver [OPTIONS] --source DSN --where WHERE
说明
可以使用DSN方式来连接数据库,DSN选项为key=value
方式,在等号的两侧不能有空格出现,并且区分大小写,多个选项之前以','(逗号)隔开
- a
归档操作是在哪个库下进行的,相当于USE
操作。 - A
指定默认字符集。 - b
当值为true
时,禁止SQL_LOG_BIN
,相当于SQL_LOG_BIN = 0
。 - D
指定包含需要归档表的数据库。 - h
指定连接的主机。 - u
指定连接的用户。 - p
指定连接需要的密码。 - P
指定连接的端口。 - S
指定连接的SOCKET文件。 - t
指定需要归档的表。 - i
指定需要使用的索引。
选项限制
- 至少指定一个选项
--dest
,--file
或--purge
。 -
--ignore
和--replace
是互斥的。 -
--txn-size
和--commit-each
是互斥的。 -
--low-priority-insert
和--delayed-insert
是互斥的。 -
--share-lock
和--for-update
是互斥的。 -
--analyze
和--optimize
是互斥的。 -
--no-ascend
和--no-delete
是互斥的。
使用示例
环境
CentOS Linux release 7.5
源库MySQL:5.7.25
目标库:5.6.43
源地址:122.152.209.19
目标地址:212.64.20.7
测试数据:
源表:pt_arch
目标表:pt_arch_new
mysql> select count(*) from tc;
+----------+
| count(*) |
+----------+
| 20 |
+----------+
1 row in set (0.16 sec)
表归档到表
目标库新建结构一致的表 pt_arch_new
归档-逐行进行-不删除原表数据-根据条件获取数据
- 不删除源表数据:加上
--no-delete
- 根据条件获取数据:
--where "id <= 10
-
注意:
若这边的条件是where 1=1
,则源表中id最大的一行的值不会被写入目标表,除非加上--no-safe-auto-increment
-- 加上了 --no-delete,不删除源表数据
pt-archiver --source h=122.152.209.19,P=13306,u=root,D=yqtest,t=pt_arch,A=utf8mb4 --dest h=212.64.20.7,P=3306,u=root,D=emjo,t=pt_arch_new,A=utf8mb4 --where "id <= 10" --progress=5000 --txn-size=1000 --statistics --no-delete --ask-pass
Enter password:
Enter password:
TIME ELAPSED COUNT
2020-12-28T17:50:58 0 0
2020-12-28T17:50:58 0 10
Started at 2020-12-28T17:50:58, ended at 2020-12-28T17:50:58
Source: A=utf8mb4,D=yqtest,P=13306,h=122.152.209.19,p=...,t=pt_arch,u=root
Dest: A=utf8mb4,D=emjo,P=3306,h=212.64.20.7,p=...,t=pt_arch_new,u=root
SELECT 10
INSERT 10
DELETE 0
Action Count Time Pct
inserting 10 0.0173 45.39
commit 2 0.0137 35.95
select 11 0.0060 15.78
other 0 0.0011 2.87
# 源表数量,没有数据被删除
mysql> select count(*) from tc;
+----------+
| count(*) |
+----------+
| 20 |
+----------+
1 row in set (0.00 sec)
# 目标表数量
mysql> select count(*) from tc_arc;
+----------+
| count(*) |
+----------+
| 10 |
+----------+
1 row in set (0.00 sec)
--source : 源
--dest : 目标,可设为自身源头地址
A : 默认字符集
--charset : 指定字符集
--where : 条件限制,全表可设置为 1=1
--progress : 每处理多少行输出一次处理信息
--txn-size : 每处理多少提交一次
--statistics : 结束的时候给出统计信息
--no-delete : 不删除源表数据
--ask-pass : 连接MySQl时提示输入密码
归档-逐行进行-不删除原表数据-全量获取但缺少最后一条最大ID值数据
- 全量获取:
--where "1 = 1
,但是源表最大ID值的数据不会被迁移过去
pt-archiver
--source h=122.152.209.19,P=13306,u=root,D=yqtest,t=pt_arch,A=utf8mb4
--dest h=212.64.20.7,P=3306,u=root,D=emjo,t=pt_arch_new,A=utf8mb4
--where "1 = 1"
--progress=5000 --txn-size=1000 --statistics --no-delete --ask-pass
归档-逐行进行-不删除原表数据-含最后一条数据
- 全量获取,含最大ID数据:加上
--no-safe-auto-increment
pt-archiver
--source h=122.152.209.19,P=13306,u=root,D=yqtest,t=pt_arch,A=utf8mb4
--dest h=212.64.20.7,P=3306,u=root,D=emjo,t=pt_arch_new,A=utf8mb4
--where "1 = 1"
--progress=5000 --txn-size=1000 --statistics --no-delete --no-safe-auto-increment --ask-pass --limit=10000
归档-逐行进行-同时删除原表数据-不含最后一条数据
- 删除源表数据:不加
--no-delete
会迁移完数据同时删除源表的数据
pt-archiver
--source h=122.152.209.19,P=13306,u=root,D=yqtest,t=pt_arch,A=utf8mb4
--dest h=212.64.20.7,P=3306,u=root,D=emjo,t=pt_arch_new,A=utf8mb4
--where "1 = 1"
--progress=5000 --txn-size=1000 --statistics --ask-pass --limit=10000
源表数据会被删除,但还保留着最大ID的一条数据
归档-逐行进行-同时删除原表数据-含最后一条数据
- 删除源表数据:不加
--no-delete
会迁移完数据同时删除源表的数据 - 含最后一条数据:
--no-safe-auto-incremen
pt-archiver
--source h=122.152.209.19,P=13306,u=root,D=yqtest,t=pt_arch,A=utf8mb4
--dest h=212.64.20.7,P=3306,u=root,D=emjo,t=pt_arch_new,A=utf8mb4
--where "1 = 1"
--progress=5000 --txn-size=1000 --statistics --no-safe-auto-increment --ask-pass --limit=10000
源表数据会被删除,但还保留着最大ID的一条数据
归档-批量进行-不删除原表数据【一般不用】
- 批量进行归档涉及的选项是
--limit
(每次查询获取行数) - 批量进行插入的选项为
--bulk-insert
- 指定选项
--bulk-insert
同时也会指定选项--bulk-delete
- 如果不想删除已归档数据,则需要指定选项
--no-delete
。 - 注意库表字符如果为utf8mb4,可能会失败,而若设置了 no-check-charset则可能有乱码
pt-archiver
--source h=127.0.0.1,P=3306,u=root,D=test,t=a,p=qweqwe --dest h=127.0.0.1,P=3306,u=root,D=test,p=1122333,t=a_arc --charset=utf8mb4 --where "1=1"
--progress=500 --txn-size=1000 --limit=10000 --no-delete --bulk-insert --no-safe-auto-increment
删除数据
不归档-直接删除-所有数据
./pt-archiver
--source h=122.152.209.19,P=3306,u=root,D=pttest,p=QWEQWE,t=tc_arc,A=utf8mb4
--where "1=1"
--progress=2000 --txn-size=1000 --statistics --purge --no-safe-auto-increment
不归档-直接删除-批量删除-所有数据
使用批量删除速度会快很多
./pt-archiver
--source h=122.152.209.19,P=3306,u=root,D=pttest,p=1122333,t=tc_arc,A=utf8mb4 --charset=utf8mb4
--where "1=1"
--progress=2000 --txn-size=1000 --statistics --limit=1000 --bulk-delete --purge
归档到文件
utf8mb4的字符集会有问题
./pt-archiver
--source h=122.152.209.19,P=3306,u=root,D=pttest,p=1122333,t=tc_arc,A=utf8
--where "1=1"
--progress=2000 --txn-size=1000 --statistics --no-delete --file='/root/tc_arc_%Y-%m-%d.sql' --output-format='dump'
常用参数
参数名称 | 描述 |
---|---|
--where 'id<50000' | 设置操作条件 |
--limit 10000 | 每次取1000行数据给pt-archive处理 |
--txn-size 1000 | 设置1000行为一个事务提交一次 |
--progress 5000 | 每处理5000行输出一次处理信息 |
--statistics | 结束的时候给出统计信息:开始的时间点,结束的时间点,查询的行数,归档的行数,删除的行数, 以及各个阶段消耗的总的时间和比例,便于以此进行优化。 只要不加上--quiet,默认情况下pt-archive都会输出执行过程 |
--charset=UTF8 | 指定字符集为UTF8 |
--no-delete | 表示不删除原来的数据。 注意:如果不指定此参数,所有处理完成后,都会清理原表中的数据 |
--bulk-delete | 指定单个语句删除chunk的方式来批量删除行,会隐式执行选项'--commit-each'。 使用单个DELETE语句删除每个chunk对应的表行,通常的做法是通过主键进行逐行的删除, 批量删除在速度上会有很大的提升,但如果有复杂的'WHERE'条件就可能会更慢(没走索引) |
--bulk-insert | --bulk-insert 使用LOAD DATA LOCAL INFILE的方法,通过批量插入chunk的方式来插入行(隐式指定选项'--bulk-delete'和'--commit-each') 而不是通过逐行单独插入的方式进行,它比单行执行INSERT语句插入的速度要快。 通过隐式创建临时表来存储需要批量插入的行(chunk),而不是直接进行批量插入操作,当临时表中完成每个chunk之后再进行统一数据加载。 为了保证数据的安全性,该选项会强制使用选项'--bulk-delete',这样能够有效保证删除是在插入完全成功之后进行的。 |
--purge | 删除source数据库的相关匹配记录 |
--local | 不把optimize或analyze操作写入到binlog里面 (防止造成主从延迟巨大) |
--analyze=ds | 操作结束后,优化表空间(d表示dest,s表示source) 默认情况下,pt-archiver操作结束后,不会对source、dest表执行analyze或optimize操作, 因为这种操作费时间,并且需要你提前预估有足够的磁盘空间用于拷贝表。 一般建议也是pt-archiver操作结束后,在业务低谷手动执行analyze table用以分析表 |
--optimize | 完成后运行OPTIMIZE TABLE。 |
--dest | 指定要存档的目标表地址。 |
--ask-pass | 连接MySQl时提示输入密码。 |