【工具】归档工具 pt-archiver

概述

官方文档: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时提示输入密码。

你可能感兴趣的:(【工具】归档工具 pt-archiver)