环境信息机器IP组件描述组件版本环境信息10.13.240.254pt-archiver3.6.0服务机10.13.222.3Mariadb10.6.21数据库安装pt-archiver# 安装 Percona 官方仓库 sudo yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm # 启用 Percona Toolkit 仓库 sudo percona-release enable tools release # 安装 Percona Toolkit sudo yum install percona-toolkit # 查看版本 pt-archiver --version # 查看帮助 pt-archiver --help清理数据脚本#!/bin/bash # # 分库分表数据清理脚本 - 直接使用你的元数据表 # 数据来源你提供的表信息 # # 连接信息配置 HOST10.13.222.3 PORT3306 USERxxx PASSWORDxxx CHARSETutf8mb4 # 清理参数配置 WHERE_CONDITIONctime 2025-01-01 LIMIT1000 TXN_SIZE500 SLEEP1 PROGRESS100000 # 日志配置 LOG_DIR/var/log/pt-archiver DATE$(date %Y%m%d_%H%M%S) LOG_FILE${LOG_DIR}/cleanup_${DATE}.log SUMMARY_FILE${LOG_DIR}/summary_${DATE}.txt # 创建日志目录 mkdir -p ${LOG_DIR} echo 开始清理任务 - $(date) | tee -a ${LOG_FILE} echo 清理条件: ${WHERE_CONDITION} | tee -a ${LOG_FILE} echo | tee -a ${LOG_FILE} # # 直接从你提供的数据生成表列表 # 格式database_name.table_name_table_number # # 生成所有表的完整名称(映射关系) TABLES( database_0.table_0 database_1.table_1 database_2.table_2 database_3.table_3 ) # 计数器 TOTAL_TABLES${#TABLES[]} SUCCESS_COUNT0 FAIL_COUNT0 TOTAL_DELETED0 CURRENT0 echo 总共需要处理 ${TOTAL_TABLES} 张表 | tee -a ${LOG_FILE} echo | tee -a ${LOG_FILE} # 开始时间 START_TIME$(date %s) # 遍历所有表 for TABLE in ${TABLES[]}; do CURRENT$((CURRENT 1)) # 拆分数据库名和表名 DB$(echo $TABLE | cut -d. -f1) TB$(echo $TABLE | cut -d. -f2) echo [${CURRENT}/${TOTAL_TABLES}] 处理表: ${DB}.${TB} - $(date) | tee -a ${LOG_FILE} # 检查表是否存在 TABLE_EXISTS$(mysql -h${HOST} -P${PORT} -u${USER} -p${PASSWORD} -N -e SELECT COUNT(*) FROM information_schema.tables WHERE table_schema${DB} AND table_name${TB} 2/dev/null) if [ ${TABLE_EXISTS} -eq 0 ]; then echo ⚠️ 表 ${DB}.${TB} 不存在跳过 | tee -a ${LOG_FILE} continue fi # 统计要删除的数据量 COUNT$(mysql -h${HOST} -P${PORT} -u${USER} -p${PASSWORD} -D${DB} -N -e SELECT COUNT(*) FROM ${TB} WHERE ${WHERE_CONDITION} 2/dev/null) echo 待删除数据: ${COUNT} 行 | tee -a ${LOG_FILE} if [ ${COUNT} -gt 0 ]; then # 执行清理 pt-archiver \ --source h${HOST},P${PORT},u${USER},p${PASSWORD},D${DB},t${TB} \ --purge \ --where ${WHERE_CONDITION} \ --limit ${LIMIT} \ --txn-size ${TXN_SIZE} \ --sleep ${SLEEP} \ --progress ${PROGRESS} \ --statistics \ --no-check-charset \ --why-quit \ --charset ${CHARSET} \ ${LOG_FILE} 21 # 检查执行结果 if [ $? -eq 0 ]; then echo ✅ 表 ${DB}.${TB} 清理成功删除 ${COUNT} 行 | tee -a ${LOG_FILE} SUCCESS_COUNT$((SUCCESS_COUNT 1)) TOTAL_DELETED$((TOTAL_DELETED COUNT)) else echo ❌ 表 ${DB}.${TB} 清理失败 | tee -a ${LOG_FILE} FAIL_COUNT$((FAIL_COUNT 1)) fi else echo 表 ${DB}.${TB} 没有需要清理的数据 | tee -a ${LOG_FILE} SUCCESS_COUNT$((SUCCESS_COUNT 1)) fi # 每张表之间添加短暂间隔 sleep 1 done # 计算耗时 END_TIME$(date %s) DURATION$((END_TIME - START_TIME)) # 输出汇总信息 echo | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 清理完成 - $(date) | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 总处理表数: ${TOTAL_TABLES} | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 成功表数: ${SUCCESS_COUNT} | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 失败表数: ${FAIL_COUNT} | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 总计删除行数: ${TOTAL_DELETED} | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 总耗时: ${DURATION} 秒 | tee -a ${LOG_FILE} ${SUMMARY_FILE} echo 详细日志请查看: ${LOG_FILE} echo 汇总信息请查看: ${SUMMARY_FILE}参数解释1. --source - 数据源连接--sourceh${HOST},P${PORT},u${USER},p${PASSWORD},D${DB},t${TB}h: 数据库主机IPP: 端口号u: 用户名p: 密码D: 数据库名t: 表名2. --purge - 只删除不归档--purge作用:只删除数据不同时归档到其他表不加的话:默认会尝试将删除的数据插入到 --dest 指定的表适用场景:直接清理过期数据不需要备份3. --where - 删除条件--wherectime 2025-01-01作用:指定要删除哪些数据实际执行:-- 每次循环实际执行的查询SELECT*FROMtableWHEREctime2025-01-01ORDERBYidLIMIT${LIMIT}⚠️ 重要: ctime字段必须有索引否则全表扫描4. --limit - 每批获取的行数--limit2000作用:每次 SELECT 查询获取多少行执行流程:第1批: SELECT... LIMIT2000第2批: SELECT... WHEREid上一批最大id LIMIT2000第3批: SELECT... WHEREid第二批最大id LIMIT2000...5. --txn-size - 事务大小--txn-size500作用:每删除多少行提交一次事务执行流程:BEGIN;DELETE WHEREid1;# 第1条DELETE WHEREid2;# 第2条...# 直到500条COMMIT;# 提交为什么小于limit: 即使一批获取2000条也分成4次事务提交避免大事务6. --sleep - 休眠时间--sleep1作用:每批数据处理完成后暂停1秒目的:给主从复制留出同步时间降低磁盘IO压力让数据库有喘息机会7. --progress - 进度显示--progress100000作用:每处理10万行输出一次进度输出示例:pt-archiver:100000rows affected(1.2sec)pt-archiver:200000rows affected(2.5sec)pt-archiver:300000rows affected(3.8sec)8. --statistics - 统计信息--statistics作用:结束时输出详细统计信息输出示例:Started at2024-01-15T10:00:00, ended at2024-01-15T10:30:00 Source:Dtest,tusers SELECT50000rows DELETE50000rows Rows affected per second:27.78...9. --no-check-charset - 跳过字符集检查--no-check-charset作用:不检查源和目标的字符集是否一致10. --why-quit - 退出原因--why-quit作用:程序退出时显示原因输出示例:Exiting because: 批处理完成(正常结束)Exiting because: 被用户中断(CtrlC)Exiting because: 连接超时(异常)11. --charset - 连接字符集--charsetutf8mb4作用:指定数据库连接的字符集执行案例开始清理任务 - Mon Mar906:34:29 UTC2026清理条件: ctime2025-01-01总共需要处理64张表[1/64]处理表: database_0.table_0 - Mon Mar906:34:29 UTC2026待删除数据:488496行 ✅ 表 bill_intl_0.fp_stat_alt_0 清理成功删除488496行[2/64]处理表: database_1.table_1 - Mon Mar906:44:50 UTC2026待删除数据:296442行结语通过此次 pt-archiver 实践我们成功实现了对 MariaDB 历史数据的高效、安全归档与清理。该工具以低负载、可控批量的方式有效缓解了表膨胀问题提升了数据库性能并为后续数据生命周期管理提供了可复用的自动化方案。建议将其纳入定期运维任务并持续监控执行效率与集群状态以保障业务稳定运行。