首批通过分布式安全可靠测评,为关键业务系统打造
OBDUMPER 工作原理
更新时间:2025-06-20 09:36
说明
本篇文档仅介绍客户端模式的运行机制。
程序会执行以下步骤:
查询源表的元数据,包含表名、列、主键(唯一键)、分区等信息。
根据分区和索引切分子任务。
多个子任务并发导出。
步骤一:OBDUMPER 导出前需要查询的元数据
OBDUMPER 需要通过查询多个系统视图来获取表的元数据。例如,列的类型及长度、分区的数量、存在主键与否与唯一索引信息。查询这些信息是为了能从 JDBC 结果集中正确获取及格式化数据,并利用主键和分区切分子任务来并行提速。
当需要导出对象的结构定义却未显式指定对象名时(例如 --all,--table '*'),需要查询对象名(表、视图、触发器、函数等)。
大部分情况下,此步骤执行缓慢的原因是某些系统视图的查询性能较差,您可以通过 sql_audit 或其他审计方法检查是否存在慢 SQL。
步骤二:OBDUMPER 切分子任务
OBDUMPER 会根据上一步查询出的元数据来切分子任务。具体来讲,先按照分区进行一次切分,如果包含主键或唯一键,则在每个分区内按照固定的行数(由 --page-size 指定,默认值一百万)进行二次切分。

所谓子任务,可以理解为一条 Query SQL。对于未进行任何切分的任务,其 Query SQL 为全表查询;对于未进行二级切分的分区,会在原有的查询语句后加上分区关键字作为限制;对于进行了二次切分的子任务,会在原有的查询语句后加上区间范围关键字作为限制。
导出生成文件名与子任务之间的关系
当启用了并行写入参数(导数工具 V4.2.7 及之后版本通过
enable.parallel.write参数开启(参见 OBDUMPER 导出数据慢?吞吐低?),导数工具 V4.2.7 之前的版本默认并发写入且无法更改),不同子任务查询出的数据会写入不同的文件,此方式会导致不同文件的大小可能不均匀。此时文件的命名规则为:{表名}.{子任务号}.{滚动号}.{文件后缀}。当未启用并行写入参数(仅导数工具 V4.2.7 及之后的版本),同一张表的子任务会写入一个文件。当然,当文件大小超过
--block-size设定的阈值,文件仍有可能发生滚动,即生成多个文件。此时文件的命名规则为:{表名}.{滚动号}.{文件后缀}(当 --block-size 不为 0)或{表名}.{文件后缀}(当 --block-size 为 0)。
步骤三:并发导出
导数工具 V4.2.7 之前的版本,不同的子任务会各自维护一个 File Writer 并写入到不同的文件,导致了数据在不同的文件中分布不均匀,且在数据量极少的情况下,也会生成多个文件。这种行为的优势在于写入文件时不存在资源竞争,整体吞吐性能最优。

导数工具 V4.2.7 及之后的版本,程序的行为有所改变,同一张表的不同子任务会使用一个唯一的 File Writer 并写入到同一个文件(在 Block Size 允许的情况下)。此方式虽然带来了并发资源竞争,但整体的行为更具有可预测性,无论切分出多少子任务,最终导出文件的数量只与 Block Size 有关。此外,由于所有数据可以直接写入到一个文件中,现在您可以同时执行多个 OBDUMPER 进程而无需担心文件的并发访问。

我们仍保留了并发写入多个文件的行为,您可以通过 enable.parallel.write 参数启用并发写入,以支持吞吐性能较为关键的场景。具体请参见 OBDUMPER 导出数据慢?吞吐低? 启用并发写入。