I've been archiving some MySQL (version 5.0.96) MyISAM tables locally and deleting from my server after checking the data. Every time the process has been pretty similar and comes off mostly without a hitch. In the case of using mysqldump for a single table here is my process...
- Create a gzipped dump of the table in question. (mysqldump -u root -p db_name table_name | gzip > table_name.sql.gz)
- Download to my local computer, reverse gzip.
- Import into the local MySQL (same version) using "source PATH". (note: online server is linux, local computer is Windows... hasn't made a difference so far though)
- Compare
CHECKSUM TABLE database.table;
of online version and local version. - Compare row count, data size, and index size. (just to be sure checksum didn't fail me somehow)
- If everything checks out, drop online table.
Like I said, mostly, this has been smooth sailing and after I'm satisfied I drop the online version of the table. However, for the most recent table I've gotten hung up on step 5 and I'm at a loss as to why exactly. On my latest import everything in step 4 and 5 matches... except the index size. It's a mismatch to the tune of 2.5 GB!
I know what you're thinking...
- The base data is most likely fine then, proceed with drop.
- Your online indexes are fragmented.
I would agree, however, my testing doesn't fully illuminate this and I want to be sure I understand what is going on before I drop the online table. (and for future reference as well)
After every previous test the index size matched upon importing the dump. Granted, it doesn't matter if point 2 applies. However, to address point 2 I ran OPTIMIZE TABLE against the online version of the table and the index size did not change.
Regarding disk space in general... I had 75 GB free locally and about 59 GB free online at the time of testing. Either should be enough for importing or optimizing and I received no messages indicating a failure in either case.
I've hit an impasse on trying to explain this discrepancy to myself. Also, I should note I ran through this entire process twice to ensure I wasn't missing something obvious. So...
Why would the size of MySQL MyISAM table indexes (aka MYI file) not match after mysqldump import?
- Fragmentation (Ran OPTIMIZE TABLE, no luck syncing size)
- Corruption (Ran through process twice and row count, data size, checksum all match)
- ...?
I can usually solve my own problems... consider me humbled. Any ideas are welcome.
PS I hope this makes for a good first question ;P
Local table after import:
+----------------+-------------+----------------+---------------+
| database.table | table_rows | data_length | index_length |
+----------------+-------------+----------------+---------------+
| database.table | 145,250,083 | 23,385,263,363 | 5,853,283,328 |
+----------------+-------------+----------------+---------------+
Online source table:
+----------------+-------------+----------------+---------------+
| database.table | table_rows | data_length | index_length |
+----------------+-------------+----------------+---------------+
| database.table | 145,250,083 | 23,385,263,363 | 8,199,018,496 |
+----------------+-------------+----------------+---------------+
mysql> OPTIMIZE TABLE database.table;
+-------------------------------------+----------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+-------------------------------------+----------+----------+----------+
| database.table | optimize | status | OK |
+-------------------------------------+----------+----------+----------+
1 row in set (17 min 41.92 sec)
mysql> SELECT CONCAT(table_schema, '.', table_name) AS 'database.table',
-> FORMAT(table_rows, 0) AS table_rows,
-> FORMAT(data_length, 0) AS data_length,
-> FORMAT(index_length, 0) AS index_length
-> FROM information_schema.TABLES
-> WHERE table_name = 'table';
+----------------+-------------+----------------+---------------+
| database.table | table_rows | data_length | index_length |
+----------------+-------------+----------------+---------------+
| database.table | 145,250,083 | 23,385,263,363 | 8,199,018,496 |
+----------------+-------------+----------------+---------------+
The table schema is below. I ran SHOW CREATE TABLE both online and locally and then put the results in two Notepad++ panes and ran "Compare". It returned as an exact match. I've obfuscated some column names, but the rest of the column (and other) definitions have remained the same.
CREATE TABLE `generic_dummy_table_name` (
`id` int(10) unsigned NOT NULL auto_increment,
`user` char(22) NOT NULL,
`num_column_1` mediumint(8) unsigned default '0',
`num_column_2` int(10) unsigned default '0',
`num_column_3` int(10) unsigned default '0',
`num_column_4` mediumint(8) unsigned default '0',
`num_column_5` mediumint(8) unsigned default '0',
`num_column_6` mediumint(8) unsigned default '0',
`num_column_7` mediumint(8) unsigned default '0',
`num_column_8` bigint(11) unsigned default '0',
`datetime_1` datetime NOT NULL default '0000-00-00 00:00:00',
`datetime_1_actual` char(29) default NULL,
`datetime_2` datetime NOT NULL default '0000-00-00 00:00:00',
`datetime_2_actual` char(29) default NULL,
`datetime_3` datetime NOT NULL default '0000-00-00 00:00:00',
`datetime_4` datetime NOT NULL default '0000-00-00 00:00:00',
`updated_at` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`created_at` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`id`),
KEY (`user`,`datetime_4`),
KEY (`datetime_4`)
) ENGINE=MyISAM AUTO_INCREMENT=1257737641 DEFAULT CHARSET=latin1
Note: The auto increment value might seem odd versus row count, but worry not... that's because this is not the first time I've archived this table.
CHECKSUM TABLE database.table;
on both tables and tell us if the checksum values are the same.