mysql删除的数据如何清理磁盘占用?

1. 服务器环境,磁盘大小1T,mysql版本5.7。存储了几千万数据,大概占用磁盘800G。

2. 问题描述?

某一天接到了需求一部分数据不需要了,需要删除一部分数据,我使用delete语句删除了一半数据

DELETE FROM `table`  WHERE ***

删除之后发现磁盘占用还是800G左右,基本没什么变化,不应该是400G吗
各种查找之后,释放磁盘占用都是用OPTIMIZE TABLE
执行OPTIMIZE TABLE会报错,磁盘空间不足,总共1T的大小,占用800G,剩下的200G不够执行OPTIMIZE TABLE命令

3. 您期望得到的结果?

扩充磁盘不太方便
数据太大,备份到本地需要时间太久,也总是各种报错不成功
想问下各位大佬,在不扩充磁盘和备份数据到本地的情况下,还有没有其他方法能释放删除数据的磁盘占用?

补充

有兄弟评论执行ALTER TABLE table_name ENGINE=INNODB;重建表可以释放空间
我试了一下执行这个也是需要空间的,和OPTIMIZE TABLE一样,剩余的200G是不够用的,都是如下报错

ERROR 1114 (HY000): The table 'table_name' is full

希望有经验的兄弟分享一下

强调一下,这800G数据是一个表的,就这一个表数据800G,别的表大小可忽略

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 23

ALTER TABLE table_name ENGINE=INNODB;

可以重建表,释放空间

1个月前 评论
lovewei 1个月前
小狼 (楼主) 1个月前

试试轮询分批清?

1个月前 评论
小狼 (楼主) 1个月前
zhuye (作者) 1个月前

笨办法,直接建个新数据库,一批一批的同步到新数据库然后备份到本地,最后在同步回服务器上

1个月前 评论

一张表一张的处理,需要的数据插入的备用表,然后TRUNCATE表,删除表,改名字,可以写个mysql存储过程执行

1个月前 评论
小狼 (楼主) 1个月前

不方便扩容磁盘,可以尝试过分批次处理,写个脚本处理下

public function optimizeTable()
{
    $batchSize = 1000; // 每批处理的记录数量
  $minId = 1; // 起始主键值

  while (true) {
        // 查询当前批次的数据范围
  $data = DB::table('table_name')
            ->where('id', '>=', $minId)
            ->limit($batchSize)
            ->get();

 if ($data->isEmpty()) {  // 如果没有数据了,结束循环
  break;
  }

        // 执行 OPTIMIZE TABLE 操作优化当前批次的数据
  DB::statement("OPTIMIZE TABLE table_name PARTITION (id >= $minId AND id < " . ($minId + $batchSize) . ")");

  $minId += $batchSize; // 更新下一批次的起始主键值
  }
}
1个月前 评论
小狼 (楼主) 1个月前
jfpl (作者) 1个月前
小猪蹄子 1个月前

先查询下表的大小看下有没有具体的减少。数据少了一半不可能没变化的吧,除非你们的数据库有开启 binlog的记录。

如果能确定删除对已有数据影响不大,可以先把mysql的binlog删掉

1个月前 评论
小狼 (楼主) 1个月前
小狼 (楼主) 1个月前
deatil (作者) 1个月前
Jyunwaa

删了一半数据没变化,不用猜都知道是二进制日志塞满了,直接暴力删除(注意保留最新的一个)

1个月前 评论
小狼 (楼主) 1个月前

普通的删除,因为是带事务的,空间释放没有那么快比较快的方式,是备份表,删除,重建

1个月前 评论
小狼 (楼主) 1个月前
raybon (作者) 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!