2021-12-07 04:08:49
Dumpling 的表内并发优化通过合理划分数据块(chunk)实现高效导出,针对不同数据库版本采用不同策略,核心目标是提升导出速度并降低资源消耗。具体优化逻辑如下:
一、表内并发的必要性Dumpling 采用生产者-消费者模型导出数据,消费者线程需并行处理不同表的数据。若表间数据量差异大,易出现线程空转或大表导出缓慢的问题。表内并发通过将大表划分为均匀的 chunk,使消费者线程可并行处理,提升导出效率。
优先选择第一列为整数的索引(主键 > 唯一索引 > 高基数索引),确保数据唯一性。
通过 EXPLAIN 估算表数据量(count),结合 rows 参数计算所需 chunk 数(count/rows)。
查询索引列的最小值(min_field)和最大值(max_field),假设数据均匀分布,计算步长 d = (max_field - min_field) * rows / count。
生成 chunk 范围:[min_field, min_field+d), [min_field+d, min_field+2d) 等。
若索引列非整数或数据分布不均,需调整索引选择或优化 rows 参数。
避免全表扫描,确保索引列能命中索引。
TiDB 为每行分配唯一 _tidb_rowid,可直接用于 chunk 划分。
但高并发写入场景下,AUTO_RANDOM 或 SHARD_ROW_ID_BITS 会导致 _tidb_rowid 分布不均,引发大 chunk 问题。
TiDB 数据以 Region 形式存储在 TiKV 上,每个 Region 管理 [StartKey, EndKey) 范围的数据。
Dumpling 通过查询 INFORMATION_SCHEMA.TIKV_REGION_STATUS 获取目标表的 Region 边界,解码出 row_id 作为 chunk 划分依据。
效果:chunk 大小与 Region 规模一致,rows 参数不再直接影响划分结果,但仍需设置以启用表内并发。
TiDB v5.0 支持聚簇索引,表不再有 _tidb_rowid,且 Region 的 StartKey 可能为非法值。
TiDB v5.0+ 提供 SELECT fields FROM table TABLESAMPLE REGIONS(),扫描每个 Region 的第一个合法 KV 对,返回聚簇索引列值。
Dumpling 利用该语法获取均匀分布的样本点,划分 chunk 范围。
优势:无需依赖 _tidb_rowid,适应聚簇索引和 Region 变化场景。
支持更多数据库(如 Oracle,需适配 driver)。
增加 Sequence 导出和 Checksum 校验,确保数据完整性。
实现 Checkpoint 功能,支持断点续导(TiDB snapshot 模式)。
代码迁移至 tidb repo,欢迎通过 #sig-migrate Slack 频道参与讨论。
总结:Dumpling 的表内并发优化通过动态适应不同数据库特性(如 MySQL 索引、TiDB Region、聚簇索引),实现高效均匀的数据划分。用户可根据实际场景调整 rows 参数,并在 TiDB v5.0+ 中利用 TABLESAMPLE REGIONS() 进一步提升导出性能。