MySQL InnoDB 中表的预定优化

Sha*_*hid 5 mysql innodb optimization

在 MySQL InnoDB 数据库中安排表的自动优化的最佳方法是什么?例如,我可以使用事件吗?我最近遇到了一个很大的性能问题(在查询时),其中一个表实际上是我数据库中最大的表,并且经常更新。我在表上运行OPTIMIZE后,问题就解决了。

Rol*_*DBA 6

OPTIMIZE TABLE 在表 (mydb.mytable) 上内部执行以下步骤

CREATE TABLE mydb.mytablenew LIKE mydb.mytable;
INSERT INTO mydb.mytablenew SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable RENAME mydb.mytablezap;
ALTER TABLE mydb.mytablenew RENAME mydb.mytable;
DROP TABLE mydb.mytablezap;
Run Code Online (Sandbox Code Playgroud)

由于涉及到 DDL,因此无法避免在操作期间对性能造成重大影响的查询。此外,不执行任何优化也同样糟糕。

您需要的是设置 MySQL 主/主(又名循环)复制

然后你可以试试这个:

对于服务器 M1 和 M2 以及指向 M1 的 DB VIP

在 M2 上,运行以下命令

STOP SLAVE;
SET sql_log_bin = 0;
Perform OPTIMIZE TABLE or ALTER TABLE ... ENGINE=InnoDB on all InnoDB tables
START SLAVE;
Wait for replication to catch (Seconds_Behind_Master = 0)
Run Code Online (Sandbox Code Playgroud)

SET sql_log_bin = 0将阻止 DDL 命令通过 Master 进行复制。

完成这些步骤后,将 Slave 提升为 Master,并将 Master 降级为 Slave(只需将 DB VIP 从 M1 移动到 M2 即可完成)。您可以每天进行此维护,除了主升级和从降级之外,生产不会受到任何影响。

您可以像这样创建脚本并在 M2 上运行它:

echo "SET sql_log_bin = 0;" > InnoDBCompression.sql
echo "STOP SLAVE;" >> InnoDBCompression.sql
mysql -u... -p... -AN -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBCompressionSQL FROM information_schema.tables WHERE engine='InnoDB' ORDER BY (data_length+index_length)" >> InnoDBCompression.sql
echo "START SLAVE;" >> InnoDBCompression.sql
mysql -u... -p... -A < InnoDBCompression.sql
Run Code Online (Sandbox Code Playgroud)

从这里开始,只需等待 M2 上的 Seconds_Behind_Master 为 0,然后将 DBVIP 从 M1 移动到 M2。现在,如果您知道要优化的表的特定名称,则可以调整查询以仅获取这些表。

试一试 !!!

警告

这是一个公平的警告:如果您已禁用innodb_file_per_table,则每次运行OPTIMIZE TABLEALTER TABLE ... ENGINE=InnoDB;ibdata1 文件都会增长。您需要清理 InnoDB 基础设施以防止 ibdata1 增长失控。