pt-archiver的实践分享,及为何要用 ob-archiver 归档数据的探讨

作者简介:肖杨,软件开发工程师

在数据密集型业务场景中,数据管理策略是否有效至关重要,它直接关系到系统性能与存储效率的提升。数据归档作为该策略的关键环节,不仅有助于优化数据库性能,还能有效降低存储成本。

在众多数据归档工具中,pt-archiver 深受 MySQL 用户青睐。我撰写此博客的目的,正是为了分享我对 pt-archiver 的亲身体验与深入测试,为大家提供一份详尽的试用报告。同时,我也借此机会向大家介绍我最近开发的 ob-archiver,这是一款专为 OceanBase 设计的数据归档命令行工具,期待能为大家带来便利与帮助。

​​​​​​​

1. pt-archiver 上手体验

最近在调研数据生命周期管理相关的工具,了解到 Percona-Toolkit 工具集中的 pt-archiver 很受 MySQL 用户的欢迎,于是打算上手体验下。Percona-Toolkit 工具集中包含了 30 多个命令行工具,已经开源了(GitHub - percona/percona-toolkit: Percona Toolkit: a collection of advanced open source command-line tools.),并且收获了 900+ Star。

废话不多说,直接上手试试吧~

1.1. 安装

# percona-toolkit 依赖 perl 环境库,需要提前安装
sudo yum install perl-DBI perl-DBD-MySQL perl-IO-Socket-SSL perl-Digest-MD5 perl-TermReadKey

# 安装 percona-toolkit rpm 包
sudo rpm -ivh percona-toolkit-3.5.5-1.el7.x86_64.rpm

# 验证 pt-archiver 命令是否可用
pt-archiver --version

1.2. 准备环境

pt-archiver 是针对 MySQL 设计的,没有对 OceanBase MySQL 模式做兼容处理。我这里使用的是 MySQL 5.7.42。

源端数据库/源表:gaoda_archive_source/employee

目标数据库/归档表:gaoda_archive_dest/employee_arc

源表的基本信息:1,000,000 rows with 6 columns

源表 DDL:

CREATE TABLE `employee` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `birthday` datetime DEFAULT NULL,
  `weight` double DEFAULT NULL,
  `gender` enum('MALE','FEMALE') DEFAULT NULL,
  `description` tinytext,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

1.3. 场景一:表归档到表

1. 在目标数据库新建相同结构的归档表(必须提前新建,否则会报错)

2. 逐行归档表数据,且不删除源端表已归档数据

3. 查看归档表数据

4. TRUNCATE 归档表,然后在上述命令增加 --limit 和 --bulk-insert 选项以批量归档

1.4. 场景二:表归档到文件

1. 归档 100,000 行表数据到文件(需要确保文件路径已存在)

2. 查看归档文件

1.5. 场景三:数据清理

1. 通过 --purge 选项执行清理,通过 --dry-run 选项可以打印 SQL 并退出而不执行任何操作(类似 EXPLAIN SQL)

2. 删除命令中的--dry-run 选项,执行数据清理

1.6. 体验小结

pt-archiver 的试用过程是比较丝滑的。作为命令行工具,其安装和使用方法简单、参数清晰易懂、日志可读性好。最重要的是轻量化,轻量化,还是 xxx 轻量化,不需要打开任何专业软件就能归档大批量数据,这体验真的很爽啊。另外 --dry-run 选项查看执行计划的功能非常亮眼。

2. pt-archiver 深入测试

用起来很爽,但我更想了解 pt-archiver 归档、清理数据的底层逻辑,比如它的数据查询和删除策略、如何保障归档准确性。PT 官方描述是:

The strategy is to find the first row(s), then scan some index forward-only to find more rows efficiently. Each subsequent query should not scan the entire table; it should seek into the index, then scan until it finds more archivable rows.

数据归档中,为了保障数据一致性和表查询效率,应该会对表结构(主键、索引、约束等)和 WHERE 条件(引用的列是否为索引列等)有一定的要求。pt-archiver 并没有在文档中作出明确说明,因此需要通过更深度地测试,分析其功能细节和使用限制。

2.1. 索引与约束

在下面的测试中,约束全部使用主键约束,索引全部使用普通索引。

先说结论:pt-archiver 数据归档时,要求源表有主键或至少包含一个索引(任意类型),对 WHERE 条件中引用的列没有特殊要求。如果表中存在主键,则使用主键拼接 WHERE 子句,并使用 ORDER BY 按序查询,使用 LIMIT 分批操作;如果表中不存在主键,则使用第一个索引。另外,pt-archiver 会添加 WHERE 子句条件限制具有 AUTO_INCREMENT 属性字段所对应的数据行操作(目的是为了在数据库重启之后,之前 AUTO_INCREMENT 的值还可以使用)。

以下是我的测试过程,不需要关注的同学建议直接跳过哈,因为太枯燥了~

2.1.1. 表-无主键无索引

CREATE TABLE `table_without_pk_and_index` (
  `col1` varchar(120) DEFAULT NULL,
  `col2` varchar(120) DEFAULT NULL,
  `col3` varchar(120) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

运行报错:"Cannot find an ascendable index in table at /usr/bin/pt-archiver line 3262, <STDIN> line 2"。尝试通过使用 --no-ascend 并取消 --no-delete 选项来禁用升序索引优化(直译的,官方描述是 Ascending Index Optimization),仍然报上述错误,可以确认 必须要有约束或索引

2.1.2. 表-有主键无索引

CREATE TABLE `table_only_with_pk` (
  `col1` varchar(120) NOT NULL,
  `col2` varchar(120) DEFAULT NULL,
  `col3` varchar(120) DEFAULT NULL,
  PRIMARY KEY (`col1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

1. where 条件使用主键(varchar 类型):执行成功,数据准确

2. where 条件使用非主键:执行成功,数据准确

使用 --dry-run查看执行 SQL 可以发现,pt-archiver 会主动去寻找主键,并利用主键 order by 和 limit 来实现 forward 寻找列,并不依赖 WHERE 条件指定索引列

3. where 条件使用主键和非主键:执行成功,数据准确

2.1.3. 表-无主键有索引

1. 仅有一个索引

CREATE TABLE `table_only_with_index` (
  `col1` varchar(255) DEFAULT NULL,
  `col2` varchar(255) DEFAULT NULL,
  `col3` varchar(255) DEFAULT NULL,
  KEY `idx_col1` (`col1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

   a. where 条件使用索引:执行成功,数据准确

   b. where 条件使用非索引:执行成功,数据准确

使用 --dry-run查看执行 SQL 可以发现,pt-archiver 会主动去寻找索引列,并利用索引列 order by 和 limit 来实现 forward 寻找列,并不依赖 WHERE 条件指定索引列,不过其 SQL 的 WHERE 子句的拼接与主键存在差异

注意,这种情况下,理论上存在丢数据风险,下文会给出复现案例。

   c. where 条件使用索引和非索引:执行成功,数据准确

2. 存在多个索引

CREATE TABLE `table_only_with_multi_index` (
  `col1` varchar(255) DEFAULT NULL,
  `col2` varchar(255) DEFAULT NULL,
  `col3` varchar(255) DEFAULT NULL,
  `col4` varchar(255) DEFAULT NULL,
  KEY `idx_col1` (`col1`),
  KEY `idx_col2` (`col2`),
  KEY `idx_col3` (`col3`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

当表中没有主键,但是存在多个索引时,pt-archiver 默认只会使用第一个索引

如果使用 --no-ascend 选项来关闭升序索引优化,并删除 --no-delete 选项来及时清理已归档的数据,则 SELECT 语句中直接不会使用任何索引:

2.1.4. 表-有主键有索引

CREATE TABLE `table_with_pk_and_index` (
  `col1` varchar(255) NOT NULL,
  `col2` varchar(255) DEFAULT NULL,
  `col3` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`col1`),
  KEY `idx_col2` (`col2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

如果表中同时存在主键和索引,则 pt-archiver 在查询中只会使用主键

1. where 条件使用非索引列

2. where 条件使用索引列

2.2. 异常案例——归档时漏数据

源表结构和数据如下:

CREATE TABLE `table_for_test` (
  `col1` varchar(120) DEFAULT NULL,
  `col2` varchar(120) DEFAULT NULL,
  `col3` varchar(120) DEFAULT NULL,
  KEY `idx_col1` (`col1`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

使用 pt-archiver 归档 WHERE col3 < 'j' 的数据,并且保留源端数据,执行以下命令:

pt-archiver --source h=xxx,P=3307,u=root,D=gaoda_archive_source,t=table_for_test,A=utf8 --dest h=xxx,P=3307,u=root,D=gaoda_archive_dest,t=table_for_test_arc,A=utf8 --charset=utf8 --where "col3 < 'j'" --progress 1 --txn-size=1 --statistics --no-delete --ask-pass --limit=5 --bulk-insert

预期应该归档 9 行数据,实际只归档了 7 条数据:

原因分析如下:

2.3. 原理浅析

根据前面的测试结果,推测 pt-archiver 的执行流程如下:

3. ob-archiver 来啦!

3.1. 功能简介

在 MySQL 领域,pt-archiver 以其轻量化、快捷易用而广受欢迎。然而在处理 OceanBase 数据库时,会遇到不兼容和效率不佳的问题:

  • 4.x 版本 OB,无法使用--bulk-insert批量插入功能。使用普通插入模式可以规避,但是性能差距约 6.5 倍
  • 3.x 版本 OB,所有功能都无法使用,语法不支持
  • 所有版本都无法设置--charset=UTF8,因为 OB 用的是 utf8mb4

针对这一问题,我们开发了 ob-archiver。ob-archiver 是基于 OceanBase ODC 数据归档引擎 打造的轻量化命令行工具,兼容 pt-archiver 的命令行选项,并对 OceanBase 数据库提供原生支持和更强大的性能:

  • 支持 MySQL 和 OceanBase MySQL 模式
  • 支持数据限流
  • 支持数据分片并发处理

「 后续会有文章揭秘 OceanBase ODC 数据归档引擎关键技术原理,例如断点恢复数据校验多维度限流自动分片等,敬请期待 😚 」

3.2. 使用样例

源表结构:

使用 ob-archiver 归档并清理源表中 col1 列在 200,000 和 700,000 之间的 499,999 行数据:

3.3. 下载使用

下载 ob-archiver 软件包并解压,按 README.md 文档指引使用。

ob-archiver-1.0.0-beta.tar.gz (15 MB)

ob-archiver-1.0.0-beta.zip (15 MB)

【结尾小彩蛋】 🎉

如果你不喜欢使用命令行工具,推荐使用 ODC(OceanBase Developer Center)体验完整的数据生命周期管理能力。可以通过 GUI 界面点点点,创建定时任务进行数据归档和清理工作,还支持断点恢复,从此解放双手,岂不美哉!点此直达。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/494723.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(一)基于IDEA的JAVA基础9

循环结构及特点 while循环 do while循环 for 循环 特点:有循环条件 循环起始值 循环自增量(每次自增的量) 循环操作 while循环 语法: 初始部分//定义变量的地方&#xff0c;声明变量 while(循环条件){ 循环操作&#xff1b; 迭代部分&#xff1b; } 流程图: 练习:打…

Rust编程(三)生命周期与异常处理

生命周期 生命周期&#xff0c;简而言之就是引用的有效作用域。在大多数时候&#xff0c;我们无需手动的声明生命周期&#xff0c;因为编译器可以自动进行推导。生命周期的主要作用是避免悬垂引用&#xff0c;它会导致程序引用了本不该引用的数据&#xff1a; {let r;{let x …

【办公类-21-11】 20240327三级育婴师 多个二级文件夹的docx合并成docx有页码,转PDF

背景展示&#xff1a;有页码的操作题 背景需求&#xff1a; 实操课终于全部结束了&#xff0c;把考试内容&#xff08;docx&#xff09;都写好了 【办公类-21-10】三级育婴师 视频转文字docx&#xff08;等线小五单倍行距&#xff09;&#xff0c;批量改成“宋体小四、1.5倍行…

2024 MCM数学建模美赛2024年A题复盘,思路与经验分享:资源可用性与性别比例 | 性别比例变化是否对生态系统中的其他生物如寄生虫提供优势(五)

审题 第四问让我们探究性别比例变化是否对生态系统中的其他生物如寄生虫提供优势。这里我们可以把问题简化一下&#xff0c;只探究性别比例会不会对寄生虫提供优势。因为考虑太多生物&#xff0c;会使模型更复杂&#xff0c;我这个水平处理不了这么复杂的问题&#xff0c;是我…

整数在内存里面的存储

整数在内存里面的存储 整数在计算机里面的存储是按照二进制的方式进行存储 显示的时候是按照16进制的方法进行显示 1. 整数在内存中的存储在讲解操作符的时候&#xff0c;我们就讲过了下⾯的内容&#xff1a;整数的2进制表⽰⽅法有三种&#xff0c;即原码、反码和补码 三种…

案例研究|DataEase实现物业数据可视化管理与决策支持

河北隆泰物业服务有限责任公司&#xff08;以下简称为“隆泰物业”&#xff09;创建于2002年&#xff0c;总部设在河北省高碑店市&#xff0c;具有国家一级物业管理企业资质&#xff0c;通过了质量体系、环境管理体系、职业健康安全管理体系等认证。自2016年至今&#xff0c;隆…

FIM配置

FIM&#xff08;功能抑制管理器&#xff09; FIM模块根据DTC状态来确定对应功能是否要禁止 FiM_GetFunctionPermission通过RTE提供给SWC FiMFIDs FiMInhibitionConfigurations FiMInhFunctionIdRef&#xff1a;关联FIMID FiMInhInhibitionMask: FIM_LAST_FAILED Inh Event…

【氮化镓】p-GaN栅极退化的温度和结构相关性

论文总结&#xff1a; 本文献深入研究了带有p-GaN栅极的正常关断型(normally-off)高电子迁移率晶体管(GaN-HEMTs)在恒定电压应力下的时序退化行为。通过直流特性分析和温度依赖性分析&#xff0c;研究了故障时间(TTF)与应力温度和器件几何结构的依赖性。结果显示&#xff0c;p…

算法打卡day19

今日任务&#xff1a; 1&#xff09;235. 二叉搜索树的最近公共祖先 2&#xff09;701.二叉搜索树中的插入操作 3&#xff09;450.删除二叉搜索树中的节点 235. 二叉搜索树的最近公共祖先 题目链接&#xff1a;235. 二叉搜索树的最近公共祖先 - 力扣&#xff08;LeetCode&…

Android 自定义EditText

文章目录 Android 自定义EditText概述源码可清空内容的EditText可显示密码的EditText 使用源码下载 Android 自定义EditText 概述 定义一款可清空内容的 ClearEditText 和可显示密码的 PasswordEditText&#xff0c;支持修改提示图标和大小、背景图片等。 源码 基类&#xf…

大语言模型(LLM)token解读

1. 什么是token&#xff1f; 人们经常在谈论大模型时候&#xff0c;经常会谈到模型很大&#xff0c;我们也常常会看到一种说法&#xff1a; 参数会让我们了解神经网络的结构有多复杂&#xff0c;而token的大小会让我们知道有多少数据用于训练参数。 什么是token&#xff1f;比…

【C语言】Infiniband驱动init_dev_assign函数

一、注释 一个内核模块的初始化函数&#xff0c;用于分配和初始化某些资源。以下是对代码块的逐行中文注释&#xff1a; // 定义一个初始化设备分配的函数 static void init_dev_assign(void) {int i 1;spin_lock_init(&dev_num_str_lock); // 初始化自旋锁if (mlx4_fil…

量化交易入门(二十三)什么是MTM指标,原理是什么

MTM指标全称是Momentum指标,翻译为动量指标。它用来衡量市场价格在一定时间内上涨或下跌的幅度,属于趋势型指标。其计算公式是: MTM(N) 当前收盘价 - N日前的收盘价 其中N表示统计的周期数,常用参数有6日、12日和24日。 MTM指标的应用要点如下: 判断趋势强弱:MTM数值越大,表…

泛型的进阶

1 通配符 &#xff1f; 我们想调用fun函数帮我们打印&#xff0c;但由于不知道Message具体是什么类型&#xff0c;所以我们可以使用 &#xff1a; &#xff1f;即通配符 当我们将fun函数中改为Message<?>此时就不会报错 2 通配符的上界&#xff1a; <? extends 上…

如何使用 ArcGIS Pro 自动矢量化水系

对于某些要素颜色统一的地图&#xff0c;比如电子地图&#xff0c;可以通过图像识别技术将其自动矢量化&#xff0c;这里为大家介绍一下 ArcGIS Pro 自动矢量化水系的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载的电子地图数据&#…

二分练习题——123

123 二分等差数列求和前缀和数组 题目分析 连续一段的和我们想到了前缀和&#xff0c;但是这里的l和r的范围为1e12&#xff0c;明显不能用O(n)的时间复杂度去求前缀和。那么我们开始观察序列的特点&#xff0c;可以按照等差数列对序列进行分块。如上图&#xff0c;在求前10个…

虚拟机Linux(centos)安装python3.8(超详细)

一、Python下载 下载地址&#xff1a;https://www.python.org/downloads/source/ 输入下面网址即可直接下载&#xff1a; python3.8&#xff1a;https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tgz python3.6&#xff1a;https://www.python.org/ftp/python/3.6.5/…

Chrome 插件 tabs API 解析

Chrome.tabs API 解析 使用 chrome.tabs API 与浏览器的标签页系统进行交互&#xff0c;可以使用此 API 在浏览器中创建、修改和重新排列标签页 Tabs API 不仅提供操作和管理标签页的功能&#xff0c;还可以检测标签页的语言、截取屏幕截图&#xff0c;以及与标签页的内容脚本…

Prompt Engineering的4 种方法

此为观看视频 4 Methods of Prompt Engineering 后的笔记。 从通用模型到专用模型&#xff0c;fine tuning&#xff08;微调&#xff09;和prompt engineering&#xff08;提示工程&#xff09;是2种非常重要的方法。本文深入探讨了prompt engineering的4种方法。 首先&#…

MySQL数据库的高级SQL语句与高级操作(2)

目录 一、子查询 1、语法: 2、以下例子均以图中两个表为基础 例子1&#xff1a;查询yun1班级大于85分的学生记录 例子2&#xff1a;将yun2班的学生记录放在一个单独的表中&#xff0c;叫yun2 例子3&#xff1a;教务处误把yun3班叫张丽的学生的成绩搞错了&#xff0c;应该为…