InnoDB vs MyISAM: Disk Space Reclamation Strategies After Row Deletion in MySQL


9 views

When dealing with MySQL storage engines, the key architectural differences between MyISAM and InnoDB directly impact disk space management:


// MyISAM file structure per table
table_name.MYD  // Data file
table_name.MYI  // Index file
table_name.frm  // Format file

// InnoDB file structure
ibdata1         // Shared tablespace
ib_logfile0     // Transaction logs
ib_logfile1
table_name.frm  // Format file

MyISAM immediately releases disk space when rows are deleted, while InnoDB's behavior varies based on configuration:


-- For MyISAM
DELETE FROM large_table WHERE date < '2020-01-01';
OPTIMIZE TABLE large_table; -- Optional for defragmentation

-- For InnoDB (with innodb_file_per_table)
ALTER TABLE innodb_table ENGINE=InnoDB; -- Recreates table to reclaim space

Converting from InnoDB to MyISAM involves several technical tradeoffs:


-- Conversion example
ALTER TABLE existing_table ENGINE=MyISAM;

-- Verify conversion
SHOW TABLE STATUS LIKE 'existing_table';

Key limitations to consider:

  • Loss of transactions (ACID compliance)
  • No foreign key constraints
  • Different locking mechanisms (table-level vs row-level)

For InnoDB, consider these approaches before converting:


-- Enable file-per-table (if not already)
SET GLOBAL innodb_file_per_table=ON;

-- Rebuild the entire tablespace
ALTER TABLE large_innodb_table ENGINE=InnoDB;

-- Monitor space usage
SELECT 
  table_name, 
  data_length, 
  index_length 
FROM 
  information_schema.TABLES 
WHERE 
  table_schema = 'your_database';

For mission-critical systems where you need both space efficiency and ACID compliance:


-- Consider using InnoDB with BARACUDA format
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=ON;
SET GLOBAL innodb_large_prefix=ON;

-- Then recreate tables with compression
CREATE TABLE compressed_table (
  id INT PRIMARY KEY,
  data TEXT
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED;

The MyISAM and InnoDB storage engines handle disk space allocation in fundamentally different ways:

-- MyISAM creates three files per table:
tablename.MYD (data)
tablename.MYI (indexes)
tablename.frm (format)

-- InnoDB primarily uses shared tablespace files
ibdata1 (system tablespace)
ib_logfile0/1 (redo logs)

When deleting data, the engines behave differently:

-- MyISAM example (space is immediately reusable):
DELETE FROM large_table WHERE id > 1000000;
OPTIMIZE TABLE large_table; -- Reclaims disk space

-- InnoDB example (space remains allocated):
DELETE FROM huge_innodb_table WHERE date < '2020-01-01';
-- Space remains in ibdata file unless using file-per-table

Converting from InnoDB to MyISAM involves these steps:

-- 1. Create MyISAM clone
CREATE TABLE myisam_version LIKE innodb_table;
ALTER TABLE myisam_version ENGINE=MyISAM;

-- 2. Copy data
INSERT INTO myisam_version SELECT * FROM innodb_table;

-- 3. Verify integrity
SELECT COUNT(*) FROM innodb_table;
SELECT COUNT(*) FROM myisam_version;

-- 4. Swap tables (atomic operation)
RENAME TABLE innodb_table TO old_innodb, myisam_version TO innodb_table;

Before switching engines, consider these benchmarks on a 10GB table:

Operation           MyISAM     InnoDB
----------------   -------    -------
INSERTs/sec        1,200      850
DELETEs/sec        950        720
Disk Space Used    8.2GB      12.4GB
Crash Recovery     45sec      8sec

Instead of converting, consider these InnoDB optimizations:

-- Enable file-per-table
SET GLOBAL innodb_file_per_table=ON;

-- Reclaim space from deleted tables
ALTER TABLE large_table ENGINE=InnoDB;

-- Monitor space usage
SELECT 
  table_schema,
  table_name, 
  data_length/1024/1024 AS size_mb
FROM information_schema.tables
WHERE engine='InnoDB'
ORDER BY data_length DESC;