TiDB v6.5.3 批量导入大事务触发 transaction is too large,数据写入失败

业务离线数据同步场景,使用单条事务执行批量 INSERT,单次写入约 45 万行业务明细数据,TiDB 版本 v6.5.3。 执行提交阶段直接抛出 transaction is too large 错误,整条事务回滚,数据无法落地。 集群 TiDB、TiKV 服务器 CPU、内存、磁盘 IO 资源均空闲,未手动修改过 tidb_max_txn_keystidb_max_txn_size 等事务限制参数,使用集群默认配置。

尝试临时调大事务上限参数后可完成写入,但了解超大事务会带来 GC 阻塞、内存占用高等风险,想咨询规范的批量写入优化方案。

3 个赞

明细表按日期 / 渠道分区,同步时只操作当日分区,单分区数据量降低;拆分写入压力。

1 个赞

默认事务阈值限制导致大批量单事务写入报错,不建议放大全局事务参数,优先拆分事务 + 分批写入,结合 TiDB 特性做规范优化。

1 个赞

将大批量数据分批次提交,缩小单事务数据量。
按分区,缩小单次写入目标分区的数据规模

1 个赞

用Dumpling导出加Lightning导入比mysqldump快很多。

拆分大事务分批提交,控制单批数据量,规避超大事务风险。

SQL兼容性和执行计划生成机制相关,同样SQL优化器决策可能不同。

  1. 事务拆分(最通用)
    把 45 万行切为小批次,每批 1000~10000 行单独提交事务,循环插入;
    离线同步场景无实时压力,性能损耗极低,完美规避大事务。
  2. 分区裁剪优化
    明细表按日期 / 渠道分区,同步仅操作当日单分区,天然缩小单次写入总量,减少单批数据量。
  3. 专用高速导入工具(海量数据首选)
    离线全量同步:使用TiDB Lightning物理导入,绕过事务限制,速度远高于 SQL INSERT
    增量批量同步:使用Dumpling+Lightning或ticdc,流式同步无大事务问题

你的 45 万行数据通常不是 key 数量超限(v6.5.3 已经默认放开 key 数限制),报错 transaction is too large 说明事务总大小超过了 100 MB。

怎么算的? 每行数据写入时,TiDB 内部会按照 KV 编码存储,每个行记录 + 每个二级索引(包括隐含的索引)都会生成独立的 KV 条目。假设你的表有 3 个索引,平均每行编码后约 300 字节,则总大小 ≈45万 ×3 ×300 B ≈405 MB,远超
100 MB 限制。
建议单条事务控制写入量,分批提交
规范的离线批量写入方案,核心原则是小事务、分批提交、批次隔离。将 45 万行按每批 3000 行拆成约 150 个独立事务,每个事务控制在 1-3 MB,远低于 100 MB 的默认限制。批次之间添加 50-100 毫秒的间隔,给 TiKV 留出 Raft
复制和 compaction 的喘息时间。同时要设计补偿重试逻辑——某一批次失败时只重试当前批次,绝不回滚已成功提交的数据。如果数据源是文件而非数据流,优先选用TiDB Lightning 物理导入模式,它直接绕过事务层生成 SST
文件,完全没有事务大小限制问题。

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。