MyISAM和InnoDB如何利用HD空间?

我的MySQL服务器快用完了HD空间。 大部分我的大表使用InnoDB引擎(没有任务关键的原因)。 为了避免可怕的“ drop database恢复innodb磁盘空间 ”响应,我想更好地理解两个引擎如何在磁盘上存储数据。

  1. 如果我要使用MyISAM,我将能够更轻松地通过删除行来恢复磁盘空间? 除了delete / truncate / empty查询之外,还有一个命令是否需要运行?
  2. 假设#1是真的:将现有InnoDB表转换为MyISAM并以这种方式恢复空间是否可行?

MySQL使用DiskSpace是相当可预测的。

information_schema可以快速地给出两个存储引擎使用多less空间。 但是, 使用innodb_file_per_tableconfigurationInnoDB要好得多 。 这样,您就可以对单个InnoDB表的磁盘空间进行微观pipe理。 如果你没有innodb_file_per_table,ibdata1将会增长,永远不会收缩。

我写了关于清理InnoDB一劳永逸的好文章。

至于MyISAM,您需要定期运行下列其中一项:

  • OPTIMIZE TABLE myisam-tablename ;
  • ALTER TABLE myisam-tablename ENGINE=MyISAM; ANALYZE TABLE myisam-tablename ALTER TABLE myisam-tablename ENGINE=MyISAM; ANALYZE TABLE myisam-tablename ;

这些将压缩MyISAM,以便在MyISAM表格组件(.MYD和.MYI)中没有未使用的数据和索引页面。

您可以使用此查询手动监视磁盘空间使用情况:

 SELECT IFNULL(B.engine,'Total') "Storage Engine", CONCAT(LPAD(REPLACE(FORMAT(B.DSize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Data Size", CONCAT(LPAD(REPLACE(FORMAT(B.ISize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Index Size", CONCAT(LPAD(REPLACE(FORMAT(B.TSize/POWER(1024,pw),3),',',''),17,' '),' ',SUBSTR(' KMGTP',pw+1,1),'B') "Table Size" FROM (SELECT engine,SUM(data_length) DSize,SUM(index_length) ISize,SUM(data_length+index_length) TSize FROM information_schema.tables WHERE table_schema NOT IN ('mysql','information_schema','performance_schema') AND engine IS NOT NULL GROUP BY engine WITH ROLLUP) B,(SELECT 3 pw) A ORDER BY TSize; 

这将告诉发动机存储引擎的数据和索引占用了多less空间。 在查询结束时注意子句:(SELECT 3 pw)。 更改数字以不同单位生成报告

 (SELECT 0 pw) for Bytes (SELECT 1 pw) for KiloBytes (SELECT 2 pw) for MegaBytes (SELECT 3 pw) for GigaBytes (SELECT 4 pw) for TeraBytes (SELECT 5 pw) for PetaBytes (Write me if you every get numbers this high) 

更新2012-05-26 22:29 EDT

对于InnoDB,如果使用innodb_file_per_table,则可能会发现.ibd文件的文件大小与data_length + index_length之和之间存在差异。

对于InnoDB表mydb.mytable ,这里是你应该做的比较:

  • 通过运行ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print %5}'获取文件的大小ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print %5}' ls -l /var/lib/mysql/mydb/mytable.ibd | awk '{print %5}'
  • 从信息schemna的angular度来获取表的大小: SELECT data_length+index_length FROM information_schema.tables WHERE table_schema='mydb' AND table_name='mytable';
  • 如果filesize > (data_length+index_length) * 1.1 ,那么你应该像这样拖动表: ALTER TABLE mydb.mytable ENGINE=InnoDB;

这将制作临时表,只将实际的数据页和索引页复制到临时表中,删除原来的,并将临时表重命名为mydb.mytable。 用一个命令即时表压缩。 请在下class时间计划所有表格按压。

MyISAM将分配给反映实际使用空间的磁盘。 如果您不使用外键,事务或InnoDB特有的任何其他function,则可以轻松转换为MyISAM。 InnoDB编写速度更快,MyISAM读取速度更快。 最终,我会build议在任意更改存储引擎之前详细研究引擎之间的差异。

这是我以前用来释放InnoDB表空间的一个过程:

从MySQL innodb中删除大量的数据