有个问题,为啥删数据时候tidb的内存也跟着涨,这个不应该基本只是在kv上的操作么

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】6.5
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】
如题在大批量数据插入的时候群里好多这种问题

删数据也是在tidb内生成带删除标记数据,提交时写到tikv

1 个赞

得先查出来啊,不查出来怎么删,你执行命令不是在tidb吗?

如果按主键删除,应该不会增加内存,如果非主键删除,还得拿上来解析下kv,看看是不是符合删除的条件。
实际上删除的过程类似于一次查询,查询到符合条件的行再删除。

大量删除数据后,会有很多无用的 key 存在,影响查询效率吧

这个是最佳答案,实际上删除对tidb来说也是插入

为啥按主键删除,不会增加内存? 删除也需要查询,也需要转换为kv对,然后也跟插入一样的操作啊,更何况删除跟插入就是标记不同而已啊,本质是一样的吧?

我大概是这个意思:
如果按照主键删除,就是pointget拿上来数据,不需要扫描全表,直接能知道哪一条数据。
如果删除不按照主键删除,就得扫描表,一条一条的全都拿上来,解析以后才能知道b列的值是什么,这时候tidb的内存增长会很快。
也就是说kv不知道sql中的b列是什么,kv只记录key:value, 像这个表大概就是 {tableid}_a: encode(a,b) ,就是说需要把value拿到tidb才能解析到b列的值是什么,所以这种非主键删除会占用很多内存。

如果说内存增长,那全都会增长的,解析一个sql,新建一个链接,都得占用内存,但是非主键删除,需要全拿上来扫一遍,肯定占用内存很多的。

这个说法不对吧,如果不是主键,假设是客户表按照身份证查找并且删除(身份证是索引,不是主键)。那么应该先按照索引查找这条记录,上锁,然后删除这一条吧,也就是也是只把这条的主键获取上来,并不是全扫一遍。

begin
many insertSQL --所有行一直hold在tidb-server层,在prewrite阶段写入tikv
commit;

begin
many updateSQL --读取所有符合条件的行,如果无需修改则数据组织时忽略,如果需要修改则组织成新行(insert) ,一直hold在tidb-server层,在prewrite阶段写入tikv
commit;

begin;
many deleteSQL --读取所有符合条件的行的rowid,在prewrite阶段将标记写入tikv
commit;

你说的对,有索引也不需要全表扫