mysql删除表数据报错_mysql 删除innodb 表里面的大量数据的问题

整理一个表table(innodb 引擎)的数据,需要大量的删除以前的数据,数据大概有999w条左右

一、直接执行 delete from table where id < 111111111;

执行很久后,报错,而且执行中途去查看,发现总条数是一样多的,并没有删除一条:

The total number of locks exceeds the lock table size.

此报错可以通过 show variables like "%_buffer%"; 调整 innodb_buffer_pool_size的值,得到一定的控制,但是这样数据量大的话,还是会有一些问题:

1、这种长事务,delete执行时会加锁,无论你有没有加锁,默认涉及到的行加写锁和Gap锁,所有相关的行都会被锁定,如果数据量大直接导致其他连接无法访问该表数据,导致业务无法使用

2、delete数据量大的时候,如果不加limilt,容易占cpu资源,导致越删越慢。

二、改用方案 用limit 的方式

直接在navicat 中执行删除100w 条的sql ,发现直接报错:

Lock wait timeout exceeded; try restarting transaction

用SELECT * FROM information_schema.innodb_trx; 命令查看 事务的情况(如下图)。

原因是:

之前的那条语句以为被kill掉了,show processlist; 里面查到确实Command 里面确实也是显示killed ,但是 查询事务的话,发现事务还是一直在堵塞 trx_state 一直是 ROLLING BACK 回滚的状态,怎么也kill 不掉。这种情况,只能等 trx_rows_modified 为0 后,此trx_id才会退出

2570fd4579aa48bc049f020090becf6f.png

14216684.html

11ce8004410b540c5f91b67a371c717f.png

14216684.html

三、用CLI 执行delete limit 的方式

trx_id 退出后,发现直接写sql在navicat里面执行,一直等待执行完了,再手动运行,这样得一直盯着。所以改用用代码CLI的方式,先查询总条数,然后循环每次删除10w条 ,然后配合

SELECT * FROM information_schema.innodb_trx; 查看事务的情况,确实是事务一直在,只要等到 trx_rows_modified 达到删除的条数时,才会执行删除成功。

总结:

如果删除的数据占表的数量百分比过大的话,建议把旧表重命令,用相同的结构建新表,然后insert into select ... where ... ; 把需要的数据导入新表。

如果删除的数据占表的数量百分比不大,但是本身数据量又不小的话,可以采用 delete limit 的CLI 代码执行的方式,期间可以观察事务的运行情况,尽量也保证删除数据的时候,数据不要写入。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值