[mysql] MySQL InnoDB not releasing disk space after deleting data rows from table

I have one MySQL table using the InnoDB storage engine; it contains about 2M data rows. When I deleted data rows from the table, it did not release allocated disk space. Nor did the size of the ibdata1 file reduce after running the optimize table command.

Is there any way to reclaim disk space from MySQL?

I am in a bad situation; this application is running in about 50 different locations and now problem of low disk space is appearing at almost all of them.

This question is related to mysql innodb delete-row

The answer is


Year back i also faced same problem on mysql5.7 version and ibdata1 occupied 150 Gb. so i added undo tablespaces

Take Mysqldump backup
Stop mysql service
Remove all data from data dir
Add below undo tablespace parameter in current my.cnf

 #undo tablespace
  innodb_undo_directory =  /var/lib/mysql/
  innodb_rollback_segments = 128 
  innodb_undo_tablespaces = 3
  innodb_undo_logs = 128  
  innodb_max_undo_log_size=1G
  innodb_undo_log_truncate = ON

Start mysql service
store mysqldump backup

Problem resolved !!


Ten years later and I had the same problem. I solved it in the following way:

  • I optimized all the databases remained.
  • I restarted my computer and MySQL on services (Windows+r --> services.msc)

That is all :)


There are several ways to reclaim diskspace after deleting data from table for MySQL Inodb engine

If you don't use innodb_file_per_table from the beginning, dumping all data, delete all file, recreate database and import data again is only way ( check answers of FlipMcF above )

If you are using innodb_file_per_table, you may try

  1. If you can delete all data truncate command will delete data and reclaim diskspace for you.
  2. Alter table command will drop and recreate table so it can reclaim diskspace. Therefore after delete data, run alter table that change nothing to release hardisk ( ie: table TBL_A has charset uf8, after delete data run ALTER TABLE TBL_A charset utf8 -> this command change nothing from your table but It makes mysql recreate your table and regain diskspace
  3. Create TBL_B like TBL_A . Insert select data you want to keep from TBL_A into TBL_B. Drop TBL_A, and rename TBL_B to TBL_A. This way is very effective if TBL_A and data that needed to delete is big (delete command in MySQL innodb is very bad performance)

Just had the same problem myself.

What happens is, that even if you drop the database, innodb will still not release disk space. I had to export, stop mysql, remove the files manually, start mysql, create database and users, and then import. Thank god I only had 200MB worth of rows, but it spared 250GB of innodb file.

Fail by design.


If you don't use innodb_file_per_table, reclaiming disk space is possible, but quite tedious, and requires a significant amount of downtime.

The How To is pretty in-depth - but I pasted the relevant part below.

Be sure to also retain a copy of your schema in your dump.

Currently, you cannot remove a data file from the system tablespace. To decrease the system tablespace size, use this procedure:

Use mysqldump to dump all your InnoDB tables.

Stop the server.

Remove all the existing tablespace files, including the ibdata and ib_log files. If you want to keep a backup copy of the information, then copy all the ib* files to another location before the removing the files in your MySQL installation.

Remove any .frm files for InnoDB tables.

Configure a new tablespace.

Restart the server.

Import the dump files.


Other way to solve the problem of space reclaiming is, Create multiple partitions within table - Range based, Value based partitions and just drop/truncate the partition to reclaim the space, which will release the space used by whole data stored in the particular partition.

There will be some changes needed in table schema when you introduce the partitioning for your table like - Unique Keys, Indexes to include partition column etc.


Examples related to mysql

Implement specialization in ER diagram How to post query parameters with Axios? PHP with MySQL 8.0+ error: The server requested authentication method unknown to the client Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver' phpMyAdmin - Error > Incorrect format parameter? Authentication plugin 'caching_sha2_password' is not supported How to resolve Unable to load authentication plugin 'caching_sha2_password' issue Connection Java-MySql : Public Key Retrieval is not allowed How to grant all privileges to root user in MySQL 8.0 MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client

Examples related to innodb

How can I rebuild indexes and update stats in MySQL innoDB? Database corruption with MariaDB : Table doesn't exist in engine How to regex in a MySQL query mysqldump exports only one table TINYTEXT, TEXT, MEDIUMTEXT, and LONGTEXT maximum storage sizes What's the difference between MyISAM and InnoDB? Why is MySQL InnoDB insert so slow? How to debug Lock wait timeout exceeded on MySQL? How to change value for innodb_buffer_pool_size in MySQL on Mac OS? #1025 - Error on rename of './database/#sql-2e0f_1254ba7' to './database/table' (errno: 150)

Examples related to delete-row

Difference between Destroy and Delete How to delete a certain row from mysql table with same column values? Delete a row from a SQL Server table Deleting records before a certain date Deleting Row in SQLite in Android Deleting specific rows from DataTable deleting rows in numpy array Delete all data in SQL Server database Deleting rows with MySQL LEFT JOIN SQL DELETE with JOIN another table for WHERE condition