关于OLAP场景下的大事务问题

【 TiDB 使用环境】
TiDB集群版本 v5.2.1

【概述】 场景 + 问题概述
目前我们在TiDB既有OLAP操作,也有OLTP操作。
像通常的OLAP操作一样,经常会使用到中间表,诸如insert into select语句。当其遇到百万数据时,会出现大事务问题,我已经尝试了如下参数,但是并没有效果

set SESSION tidb_dml_batch_size = 20000;
set SESSION tidb_batch_insert = True;
set SESSION tidb_batch_commit = True;

这种情况下我改如何操作?

我并不想让全局开启大事务,只想在进行OLAP操作的session中允许大事务。因为我明确的知道我的OLAP操作只会读取原始数据表,并不会出现“因开启分批事务修改原始数据导致的数据数据不一致“问题。但仍然想让OLTP操作受大事务限制

HTAP 的核心,就是写一份数据,TP 和 AP 都可以用

实际上你开启的 batch 的参数,就是针对 TP 的,对 AP 无效
AP 的数据是由 raft 协议,从 TP 这边同步过去的

希望对你有所帮助~

可能是我表述有些问题,这里我想讲的就是tikv开启大事务。
目前我的意图为
1、常规的OLTP业务,即单条插入ods表数据的业务不变,依旧受大事务限制
2、创建一张中间表,某些OLAP业务一条sql无法实现,只能通过先将中间数据输出到中间表(此时如果中间数据几百万,则会被大事务卡住,我希望单独在这个session允许开启batch)。
然后通过中间表和其他表进行join,最终将结果输出到客户端

这种OLAP操作在大数据处理中应该是比较常见的

针对特定session开启 大事务不影响global的连接。
目前的情况是 设置不生效的问题。
解决思路:
1、把中间ibao生产改成小事务 (走批)
2、确定是不是bug。

1 个赞

1、中间表的生产理论上是无法改成走批的。
一个原因是,分批去查的话不会享受到MVCC,会出现数据不一致问题。
另一个原因,由于查询本身已经比较复杂了,数据量也很多,如果分批必然少不了分页排序,会对tidb造成很大压力
2、这个大事务问题是可以复现的,复现方式如下:

1、首先制造一张表,里面预先存好100W条数据
2、设置session,开启如下参数允许大事务
set SESSION tidb_dml_batch_size = 20000;
set SESSION tidb_batch_insert = True;
set SESSION tidb_batch_commit = True;
3、执行sql
insert into x_tab select * from x_tab;

我这边怀疑是这些参数在5.x版本里面被取消了,或者说需要一些其他参数配合才可执行大事务?

这个参数是跑批用的,不是大事务的玩法,大事务需要更多的内存来支持,

你参考下,我写的文档吧:

1 个赞

这样试试
SET @@SESSION.tidb_batch_insert = 1;
SET @@SESSION.tidb_batch_delete = 1;
SET @@SESSION.tidb_dml_batch_size = 500;

您好,这篇文章已经学习。大概是我tidb没配置enable-batch-dml该参数。

但是想请教下,enable-batch-dml该参数开启,是意味着允许session自主选择开启batch insert,默认是关闭。
还是说enable-batch-dml该参数开启即全局默认开启batch呢?

目前我从google搜索关键词tidb enable-batch-dml并未找到针对它的详细介绍


你可以选择不开启…

您好,已经实验过,该操作确实有效,已采纳为最佳回答。

另外想确认下,tidb_batch_insert开启的情况下,无法保证插入的原子性,那它是否能保证读取的快照呢?
从理论上讲,在查询的时候会对请求赋予一个具备时间戳功能的id,可以根据该id做到MVCC读,该参数是否会破坏MVCC读?

例如我正在运行insert into y_tab select * from x_tab,是否会受到x_tab数据持续变更的影响?

1 个赞

这些只能在业务或者数据逻辑层面去考虑完整性了,比较复杂

batch 就是分批的方式,需要校验所有的 batch 是否全部完成,没完成的时候,有没有前后依赖,是否需要回退还是继续处理

如果业务场景必须要求严格的一致性,这种用法就不合适

这个问题和 MVCC 无关…
MVCC 就是为了解决数据在时间点上的隔离性

楼上的大佬说的是对的
set @@session.tidb_batch_insert = 1
set @@session.tidb_batch_delete = 1
set @@session.tidb_dml_batch_size = 500
batch 就是分批的方式

我大概理解了,之前我一直理解的batch是针对整条语句的。
也就是说我误以为insert into select这样的语句,select部分会被batch_insert参数拦断成一个个小事务。

现在看来,batch_insert应该只是针对insert into部分,对select毫无影响

我感觉文档白写了… :rofl:
你现在才明白…

写个循环分批提交啊,很简单。

咋写?
我是insert into select join,这种情况下我没法用offset分批的,也不可能把数据拉到本地再传上去

select里面用条件比如时间分为几块不行吗

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