美文网首页
TiDB异常处理:transaction is too larg

TiDB异常处理:transaction is too larg

作者: MrEthanLee | 来源:发表于2019-10-30 16:36 被阅读0次

    背景

    由于TiDbiB是一个支持ACID的分布式数据库,受限于事务大小的严格控制,日常Hive与TiDB大批量数据交互的过程中,常常会出现如下错误:

    Error Code:8004.transaction is too large
    

    原因

    以下摘自TiDB官方解释文档

    由于分布式事务要做两阶段提交,并且底层还需要做Raft复制,如果一个事务非常大,会使得提交过程非常慢,并且会卡住下面的Raft复制流程。为了避免系统出现被卡住的情况,对事务的大小做了限制:

    • 单个事务包含的SQL语句不超过5000条(默认)
    • 单条KV entry不超过6MB(SQL层面:单行数据不大于6MB)
    • KV entry的总条数不超过30w(SQL层面:总的行数*(1+索引个数)<30w)
    • KV entry的总大小不超过100MB(SQL层面:一次提交的全部数据小于100MB)

    注意:无论是大小限制还是行数限制,还要考虑TiDBit做编码以及事务额外Key的开销,建议每个事务的行数不超过200行,且单行数据小于100k,否则可能性能不佳。

    解决方案

    insert&select

    --开启隐藏函数
    set @@session.tidb_batch_insert = 1;
    --事务完成后,关闭
    set @@session.tidb_batch_insert = 0;
    

    注意:insert会把大事务分批执行,避免超时的同时会导致事务原子性的丢失。

    update&delete

    for i from 0 to 23:
        while affected_rows <> 0:
            delete * from table where insert_time >= i:00:00 and insert_time < (i+1):00:00 limit 5000;
            affected_rows = select affected_rows()      
    

    注意:通过循环方式删除数据可能会导致速度越来越慢,因为每次删除都是从前向后遍历,前面数据删除后,短时间内会残留删除标记(后续会被gc掉),从而影响后面的Delete语句。因此建议将where条件细化,见上伪代码。

    相关文章

      网友评论

          本文标题:TiDB异常处理:transaction is too larg

          本文链接:https://www.haomeiwen.com/subject/btxavctx.html