加速 MyISAM 到 InnoDB 的转换

Der*_*ney 15 mysql-5 storage-engine

我有一个 mysql 5.1 服务器,其中包含大约 450 个表的数据库,占用 4GB 。这些表中的绝大多数(除了 2 个)都是 MyIsam。这在大多数情况下都很好(不需要事务),但是应用程序一直在增加流量,并且某些表由于更新时的表锁定而受到影响。这就是现在有 2 个表是 InnoDB 的原因。

较小表(100k 行)上的转换根本不需要很长时间,从而导致最少的停机时间。然而,我的一些跟踪表接近 5000 万行。有没有办法ALTER TABLE...ENGINE InnoDB在大桌子上加速?如果没有,是否有其他方法可以最大限度地减少这些写入繁重表的停机时间?

ran*_*omx 10

首先让我说,我讨厌 ALTER。这是邪恶的,恕我直言。

说,这是您当前的表架构 -

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)

这是我推荐的路径-

创建一个将替换旧表对象的新表对象:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)

按名称将旧表中的所有行插入到新表中:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;
Run Code Online (Sandbox Code Playgroud)

冒烟测试您的迁移:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;
Run Code Online (Sandbox Code Playgroud)

交换表名,以便您可以在需要回滚时保持备份。

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;
Run Code Online (Sandbox Code Playgroud)

继续进行回归测试。

对于具有多个索引和数百万行的表,这种方法变得越来越可取。

想法?


Bri*_*ton 7

1) 损失保护是偏执的功能。始终进行备份。如果您真的很偏执,请进行备份,然后从备份中恢复。

2) MySQL 手册的这一页有转换表类型的说明。

将表更改为 InnoDB 的最快方法是直接插入 InnoDB 表。也就是说,使用 ALTER TABLE ... ENGINE=INNODB,或创建一个具有相同定义的空 InnoDB 表并使用 INSERT INTO ... SELECT * FROM ... 插入行。

3) PostgreSQL 做全文搜索Sphinx引擎似乎是为 MySQL 做的