MySQL: reducing ibdata file size for MyISAM tables

mysql

Solution

ibdata1 and MyISAM are mutually exclusive.

First thing you should do is count how many tables use both storage engines:

SELECT COUNT(1) EngineCount,engine
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','performance_schema','mysql')
GROUP BY engine;

If SOME tables are InnoDB:

Perform my CleanUp of InnoDB

- Howto: Clean a mysql InnoDB storage engine?

- https://dba.stackexchange.com/questions/8982/is-there-any-best-way-to-reduce-the-size-of-ibdata-in-mysql/8983#8983

If you have only MyISAM tables and no InnoDB tables:

First, eliminate any traces of InnoDB Do the following:

STEP01) Add this to my.cnf

[mysqld]
skip-innodb

STEP02) `service mysql restart`

STEP03) `rm -f /var/lib/mysql/ibdata1 /var/lib/mysql/ib_logfile*`

After these steps, you can perform a Compression of Each MyISAM tables like this:

For the table mydb.mytable that is MyISAM, just run one of the following:

- `OPTIMIZE TABLE mydb.mytable;`

- `ALTER TABLE mydb.mytable ENGINE=MyISAM; ANALYZE TABLE mydb.mytable;`

If you want to defrag all your MyISAM tables, here is a shell script to do so...

MYSQL_USER=root
MYSQL_PASS=rootpassword
MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}"
SQL="SELECT CONCAT('OPTIMIZE TABLE ',table_schema,'.',table_name,';') "
SQL="${SQL} FROM information_schema.tables "
SQL="${SQL} WHERE engine='MyISAM' AND table_schema NOT IN "
SQL="${SQL} ('information_schema','performance_schema','mysql')"
mysql ${MYSQL_CONN} -ANe"${SQL}" > GlobalMyISAMOptmizeTable.sql
less GlobalMyISAMOptmizeTable.sql

Once you trust the script visually, just run it

mysql ${MYSQL_CONN} < GlobalMyISAMOptmizeTable.sql

Give it a Try !!!

UPDATE 2012-07-25 09:52 EDT

I would like to clarify one of my suggestions for compression of MyISAM

I said earlier

- `OPTIMIZE TABLE mydb.mytable;`

- `ALTER TABLE mydb.mytable ENGINE=MyISAM; ANALYZE TABLE mydb.mytable;`

These commands are mechanically identical. `OPTIMIZE TABLE` performs a defrag of the MyISAM table and then runs `ANALYZE TABLE` to compute fresh index statistics.

Mechanically speaking, this is what `ALTER TABLE mydb.mytable ENGINE=MyISAM;` does:

CREATE TABLE mydb.mytabletmp LIKE mydb.mytable;
INSERT INTO mydb.mytabletmp SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable RENAME mydb.mytablezap;
ALTER TABLE mydb.mytabletmp RENAME mydb.mytable;
DROP TABLE mydb.mytablezap;

Problem

My Question is actually very similar to this one and also includes a good answer for a case with InnoDB Engine tables: https://dba.stackexchange.com/questions/8982/is-there-any-best-way-to-reduce-the-size-of-ibdata-in-mysql/8983#8983, I have noticed that drop schema do not shrink ibdata files , so i have looked for a methods to configure the DB so that the size will be reduced after deleting a schema. i have found many links talking about InnoDB and the way to save table per file so that the .frm file it self will contain the table data and it will be reduced. But what happens with MyISAM tables (with more than 5G table size).

Original source

Related problems