【问题标题】:MySQL: reducing ibdata file size for MyISAM tablesMySQL:减少 MyISAM 表的 ibdata 文件大小
【发布时间】:2012-07-23 00:54:21
【问题描述】:

我的问题实际上与这个问题非常相似,并且还包括对 InnoDB 引擎表案例的一个很好的答案:

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

我注意到 drop schema 不会缩小 ibdata 文件,所以我一直在寻找一种方法来配置 DB,以便在删除 schema 后减小大小。

我发现很多链接都在谈论 InnoDB 以及每个文件保存表的方式,这样 .frm 文件本身将包含表数据并且会减少。

但是 MyISAM 表会发生什么(表大小超过 5G)。

【问题讨论】:

  • 有很多帖子都谈到了ibdata。 BTW ibdata 适用于 innodb 而不是 myisam。 myd 代表 myisam。

标签: mysql


【解决方案1】:

ibdata1 和 MyISAM 是互斥的。

您应该做的第一件事是计算有多少表同时使用这两种存储引擎:

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

如果某些表是 InnoDB:

执行我的 InnoDB 清理

如果你只有 MyISAM 表而没有 InnoDB 表:

首先,消除任何 InnoDB 的痕迹 执行以下操作:

STEP01) 将此添加到 my.cnf

[mysqld]
skip-innodb

STEP02) service mysql restart

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

在这些步骤之后,您可以像这样执行每个 MyISAM 表的压缩:

对于 MyISAM 表 mydb.mytable,只需运行以下命令之一:

  • OPTIMIZE TABLE mydb.mytable;
  • ALTER TABLE mydb.mytable ENGINE=MyISAM; ANALYZE TABLE mydb.mytable;

如果您想对所有 MyISAM 表进行碎片整理,这里有一个 shell 脚本可以执行此操作...

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

一旦您在视觉上信任脚本,只需运行它

mysql ${MYSQL_CONN} < GlobalMyISAMOptmizeTable.sql

试试看!!!

更新 2012-07-25 09:52 EDT

我想澄清我对 MyISAM 压缩的建议之一

我之前说过

  • OPTIMIZE TABLE mydb.mytable;
  • ALTER TABLE mydb.mytable ENGINE=MyISAM; ANALYZE TABLE mydb.mytable;

这些命令在机制上是相同的。 OPTIMIZE TABLE 对 MyISAM 表执行碎片整理,然后运行 ​​ANALYZE TABLE 以计算新的索引统计信息。

从机械上讲,这就是ALTER TABLE mydb.mytable ENGINE=MyISAM; 所做的:

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;

【讨论】:

  • 感谢非常有建设性的回答!
  • 为什么我需要更改表 mydb.mytable ENGINE=MyISAM;如果它已经是 MyISAM?
【解决方案2】:

如前所述,MyISAM 不应该使用 ibdata。 您的 my.cnf 或 MySQL shell 类型中的 innodb 设置是什么:

    SHOW VARIABLES LIKE "%innodb%";

这些变量设置了吗?

    innodb_data_home_dir
    innodb_data_file_path

如果您根本不使用 INNODB,您应该能够安全地删除 ibdata 和 ib_logfile(s) 并重新启动 MySQL。通常,尽管在不首先删除表的情况下删除这些会导致问题。 见How to shrink/purge ibdata1 file in MySQL

如果您确实有超过 5Gigs 的 MyISAM 表,建议您还是使用 INNODB。 (任何超过 4 Gigs)。 要排除故障,您可以尝试添加

    skip-innodb 

如果您根本不使用 INNODB,请在 my.cnf 中。

【讨论】:

  • 我无法将表更改为 INNODB,因为它会降低读取性能,我有很多读取和少量写入
猜你喜欢
  • 2011-01-10
  • 1970-01-01
  • 2020-04-23
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
  • 2018-09-15
  • 2011-07-25
  • 1970-01-01
相关资源
最近更新 更多