删除表,对应的数据没有被物理删除。

【 TiDB 使用环境】生产环境 /测试/ Poc
【 TiDB 版本】V7.1.1
【复现路径】做过哪些操作出现的问题
【遇到的问题:问题现象及影响】
【资源配置】
【附件:截图/日志/监控】
如题,我把一张表给删了,其对应的数据没有被物理删除,是不是有类似回收站机制呢?应该怎么删除对应的数据呢?

有gc的,默认十分钟。等会再看看。

都等了一个晚上,还是没有删除

看下gc的配置呢
show variables like ‘%tidb_gc_life_time%’;

这个是10分钟。

MVCC就是这样的啊

没明白你的意思,可以详细讲一下吗?

MVCC机制

但是我现在是想把数据删了,应该怎么做呢?不然就会有好几个T的垃圾数据。

select tikv_gc_last_run_time,tikv_gc_safe_point from mysql.tidb

查下这个看看gc实际执行情况

这个应该是GC的机制去删除的。

但是据我观察,经过一个晚上也没有删除。

这个好像也没啥办法吧,只能等gc清理了

SELECT * FROM mysql.tidb WHERE variable_name ='tikv_gc_safe_point;可以查查清理到哪一个时间点了

参考这里排查一下吧

TiDB 的事务的实现采用了 MVCC(多版本并发控制)机制,当新写入的数据覆盖旧的数据时,旧的数据不会被替换掉,而是与新写入的数据同时保留,并以时间戳来区分版本。

delete删除语句在TiDB处理方式是标记删除,删除本身实际上也是插入一条kv记录,只不过value变成了delete,最后通过逻辑GC和compaction来删除真实数据。所以,循环执行delete 语句,每次删除n条记录,下一次delete语句要扫描的key就会+n,执行时间越来越长(大家可以去做个实验,观察慢日志文件,同样的delete语句total keys会不断增加)。

那么,怎样去删除&归档特定日期前的记录比较高效呢?

首先,我们知道TiDB对事务大小是有限制的

  1. 单个事务包含的SQL语句不超过5000条
  2. 操作的单条记录不超过 6MB
  3. 事务操作的总keys不超过 30w
  4. 事务操作的所有记录总大小不超过 100MB
    由于TiDB的事务限制和TiDB mvcc的实现原理,想要删除&归档一个特定范围的数据,目前没有太好的方法。整理一些个人心得供大家参考:
    第一种方式:
    尽量缩小范围删除的粒度,比如提前按分钟将数据分段,打开tidb_batch_delete,提高并发去删除。注意使用开闭区间,分段之间不要出现冲突,TiDB解决事务冲突的代价比较大。
set @@session.tidb_batch_delete=1;
delete from table where create_time > '$start_step' and create_time <= '$end_step';

如果分段内的数据超出事务大小限制,TiDB会自动将delete操作拆分成多个batch。个人亲测,这种方式删除数据的速度还是比较快的。
第二种方式:
按照日期分表,删除过期的表即可。TiDB删表是秒级的,后续空间回收也比较快,缺点是侵入业务。两种方式各有利弊,大家可以各取所需。

1 个赞

先看下这个吧,一直没有释放的事务也会阻止自动gc

我之前遇到类似的问题,但是删除后tidb数据库默认的垃圾回收时间是10分钟,然后就自动释放空间了。如果还是没有,你确认是gc回收机制是否关闭或者设置的时间是多少。如果以后有类似需求,可以使用TRUNCATE TABLE语句来清空表中的所有数据。这个语句会立即释放表中占用的存储空间,并将所有数据行都标记为已删除