【 TiDB 使用环境】测试
【 TiDB 版本】7.5
【复现路径】通过mysql客户端连到tidb后,执行delete删除大量数据,执行一段时间后报错"ERROR 2013 (HY000): Lost connection to MySQL server during query",请问是何原因
oom了
删除官方有最佳实践 一般是delete limit 1000
删除的数据量比较大,超出了tidb的内存限制:tidb_mem_quota_query
有快速删除数据的方法吗,limit 数据量大删除很慢
查询:
show variables like ‘%quota%’;
tidb_mem_quota_query====>每条SQL占用缓存的大小
show variables like ‘%oom%’;
tidb_mem_oom_action | CANCEL | 或LOG===>直接记录到日志文件中
tidb_mem_oom_action====>如果每条SQK占用缓存的大小超过tidb_mem_quota_query值的时候,
并且启用临时磁盘,临时磁盘没有空间,由此参数控制具体是取消还是继续使用
启用临时磁盘:
show variables like ‘tidb_enable_tmp_storage_on_oom’;
| tidb_enable_tmp_storage_on_oom | ON |
show config where name like ‘%tmp-storage-path%’;
tmp-storage-path
show config where name like ‘%tmp-storage-quota%’;
tmp-storage-quota
两种解决方法:
1、使用脚本分批次删除,每次取出一定量的数据删除
2、修改上面参数值
先改成8G试试
set global tidb_mem_quota_query=8589934592
内存多大都有可能爆的风险,建议控制数据量分批删,控制事务大小,减少内存占用。
update delete操作大批量数据建议 加limit ,另外建议设置oom的内存阈值
批量删除过多数据可以使用保留数据跑批到新表----->drop旧表---------->再rename新表,通过datax创建一个任务可以定期执行,我们在生产上面有类似的你可以参考此种解决方法。
再就是上面说的通过limit方法。GC时间,还有就是tidb_mem_quota_query设置,看硬件实际情况
这是事务过大时间过长造成的,更改成小事务
服务挂 了吧。
尝试 修改 TiDB 全局参数 wait_timeout
来增加超时时间
给你个脚本可以大规模删除数据
date1=date -d “1 day ago” +“%Y-%m-%d”
echo $date1
delete_db_sql=" delete from xxxx a where a.xxxx < ‘2023-01-01 00:00:00’ and a.xxxx = ‘2’ limit 10000;"
echo $delete_db_sql
i=0
while ((++i)); do
a=$(/bin/mysql -uroot -pxxxx -A soa_vehicle -hx.x.x.x -P 4000 --comments -e “${delete_db_sql}” -vvv|grep “Query OK” |awk ‘{print $3}’)
echo $a
if (($a<1)); then
break 1
fi
sleep 1
printf “%-4d” $((i))
done
除了上面的一些专业建议,如果删除的数据量占表的绝大部分,并且业务能接受,可以选择新建空表,把需要留下的数据迁移到新表,然后drop掉老表,再把新表表名修改成老表表名。
没人用delete删除大量数据这么玩,一般都是脚本分批删除
果断收藏了。
此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。