开头还是介绍一下群,如果感兴趣PolarDB ,MongoDB ,MySQL ,PostgreSQL ,Redis, Oceanbase, Sql Server等有问题,有需求都可以加群群内,可以解决你的问题。加群请联系 liuaustin3 ,(共1780人左右 1 + 2 + 3 + 4 +5) 4群(300+),另欢迎 OpenGauss 的技术人员加入。
这里先做一个广告,在12月28日应邀,有异常分享活动,这里做一个广告
DBA 在日常的工作中,数据归档是DB 人员工作中的必选项。这里有技术的因素和法律的因素,数据库中的业务在使用一段时间内,数据表中必然存在大量的过期的数据,这些数据将不在与当前的业务有关,同时这些数据的存在会影响当前一些SQL 的执行的性能,所以从技术的角度需要进行数据的归档。从法律的因素来讲,数据也是资产,有些数据有恢复和追溯的可能性。
数据归档的方法有很多,基于不同场景,在大批量MySQL 数据库需要归档的情况下,一些使用存储过程,或使用手动的方式都不应该是我们常规的选择,工具化以及可以集成化的手段才是我们需要学习和使用的。
pt-archiver 工具是一个满足在数据归档情况下,同时可以将数据进行清理的程序,他可以将数据插入到另一个表中,或写入文件中的方式进行数据的归档的处理。本身pt-archiver可以支持在归档程序中插入复杂的归档的逻辑进行数据的归档,在通过pt_archiver进行归档的首要注意的部分是表需要有主键的情况下才能进行数据的归档,在数据归档中严禁不指定任何的索引,进行数据归档的行为,因为pt-archiver 的设计是从它选择的索引起始位置开始向前扫描。
同时我们需要弄清楚一点数据归档不是数据备份,数据备份要求的数据的所有表的一致性在备份时间点,但数据归档,是根据业务逻辑将数据抽离走,这点类似ETL的一个过程。
下面列举一些,pt-archiver 中的选项
1 --no-check-columns 默认的情况下,pt_archiver 是要检查原表与目的表之间的字段是否都吻合,数据类型是否匹配。特殊情况下可以通过选项将这个问题忽略
2 --no-check-charset 默认的情况下,pt-archiver 是要检测链接和表之间的字符集是否匹配,在一些情况下通过添加此配置忽略这个设置
3 --columns 在归档中如果目的表和目的文件不需要原表的所有的信息可以退通过此参数来进行数据归档中过滤部分需要的字段进行数据的处理,字段通过逗号来进行分割。
4 --for-update 如果使用了次参数,在对数据库表进行数据的处理读取数据添加此参数后,可以在 select 数据库时添加for update 后缀,保证读取时行的一致性。
5 --limit 这里的在归档中,这个部分默认的每次处理的数据是1行,调整大这个部分可以提高归档的速度,但调整过大会影响在业务期间的查询部分,尤其添加了for update参数
6 --low-priority-delete 在进行清理的数据的时候,对于删除的操作降低他的操作的等级,降低性能影响。
7 --no-delete 默认的情况是归档的行就要被清理和删除,添加--no-delete 后相当于将pt-archiver 变为数据迁移工具。
8 --progress 将工作的进度进行展示
9 --replace 将数据插入的语句更换成 replace
10 --retries 默认值为1 ,在操作超时或死锁的情况下,操作会重试多少次,默认1次
11 --skip-foreign-key-checks 在数据处理中禁止外键检查
12 --sleep¶在数据 fetch的情况下,每次的fetch 间隔时间
13 --where 条件
14 --analyze 在操作归档删除后,对原表进行analyze 的操作
根据这些条件,我们下面举一个例子
我们在world_x 数据库中有一个表city 同时我们将表归档到 city_new中,命令是这样写的,这里pt-archiver 使用的是最新的版本。
City 表
go
mysql> select * from city limit 10;
+----+----------------+-------------+---------------+-------------------------+
| ID | Name | CountryCode | District | Info |
+----+----------------+-------------+---------------+-------------------------+
| 1 | Kabul | AFG | Kabol | {"Population": 1780000} |
| 2 | Qandahar | AFG | Qandahar | {"Population": 237500} |
| 3 | Herat | AFG | Herat | {"Population": 186800} |
| 4 | Mazar-e-Sharif | AFG | Balkh | {"Population": 127800} |
| 5 | Amsterdam | NLD | Noord-Holland | {"Population": 731200} |
| 6 | Rotterdam | NLD | Zuid-Holland | {"Population": 593321} |
| 7 | Haag | NLD | Zuid-Holland | {"Population": 440900} |
| 8 | Utrecht | NLD | Utrecht | {"Population": 234323} |
| 9 | Eindhoven | NLD | Noord-Brabant | {"Population": 201843} |
| 10 | Tilburg | NLD | Noord-Brabant | {"Population": 193238} |
+----+----------------+-------------+---------------+-------------------------+
10 rows in set (0.00 sec)
运行下面的命令,这里city表中最大的ID 没有超过5000,这相当于整体进行数据的归档,并清空city 表。
go
pt-archiver --source h=192.168.198.101,u=admin,p=admin,P=3306,D=world_x,t=city --dest h=192.168.198.101,u=admin,p=admin,P=3306,D=world_x,t=city_new --where "id < '5000'"
但在归档后,我们发现一个问题,使用pt_archiver 归档中,有一条记录并未进行归档,到 city_new表。
这里也做了反向的测试,在测试中,city_new 到 city 表也会缺一条数据,而且是有规律的都是最后一条数据。经过查询,这与数据库表的自增与pt_archiver 中的 safe-auto-increment 有关,在默认的情况下工具会计算归档数据库的自增与步长,等所以归档期间会会保护一行数据,这里通过参数 --no-safe-auto-increment 来进行数据的归档,会忽略保护措施,归档的数据就与原有的条件对应了。
go
pt-archiver --source h=192.168.198.101,u=admin,p=admin,P=3306,D=world_x,t=city_new --dest h=192.168.198.101,u=admin,p=admin,P=3306,D=world_x,t=city --no-safe-auto-increment --where "id < 5000"