标签(空格分隔): 高性能MYSQL 第四章 schema与数据类型 加快ALTER TABLE操作的速度


MySQL的ALTER

  TABLE操作的性能对来说是个大问题。MySQL执行大部分修改表结构操作的方法是用新的结构创建一个空表,从旧表中查出所有数据插入新表,然后删除旧表。

  一般而言,大部分ALTER TABLE操作将导致MySQL服务中断。对常见的场景,能使用的 技巧只有两种:
1.1. 一种是先在一台不提供服务的机器上执行ALTER TABLE操作,然后和提供服务的主库进行切换;

1.2. 另外一种技巧是“影子拷贝”。影子拷贝的技术是用要求的表结构创建一张和源表无关的新表,然后通过重命名和删表操作交换两张表。

只修改.frm文件

  修改表的.frm文件是很快的,但MySQL有时候会在没有必要的时候也重建表。如果愿意冒一些风险,可以让MySQL做一些其他类型的修改而不用重建表。

我们下面要演示的技巧是不受官方支持的,也没有文档记录,并且也可能不能正常工作,采用这些技术需要自己承担风险。建议在执行之前 首先备份数据!

下面这些操作是有可能不需要重建表的:

  • 移除(不是增加)一列的AUTO_INCREMENT属性。
  • 增加、移除,或更改ENUM和SET常量。如果移除的是已经有行数据用到其值的常量,查询将会返回一个空字串值。
      基本技术是为想要的表结构创建一个新的.frm文件,然后用它替换掉已经存在的那张表的.frm文件,像下面这样:
      1. 创建一张有相同结构的空表,并进行所需要的修改(例如增加ENUM常量)。
      2. 执行FLUSH TABLES WITH READ LOCK。这将会关闭所有正在使用的表,并且禁止任何表被打开。
      3. 交换.frm文件(重全名)。
      4. 执行UNLOCK TABLES来释放第2步的读锁。

InnoDB快速载入数据

  在MyISAM中有一个常用的技巧是禁用索引(只能禁用非唯一索引)、载入数据,然后重新启用索引。在现代版本的InnoDB版本中,有一个类似的技巧,这依赖于InnoDB的快速在线索引创建功能。这个技巧是,先删除所有的非唯一索引,然后增加新的列,最后重新创建删除掉的索引。Percona Server可以自动完成这些操作步骤。
  也可以使用像前面据说的ALTER TABLE的骇客访求来加速这个操作,但需要多做一些工作并且承担一定的风险。这对从备份中载入数据是很有用的,例如,当已经知道所有数据都是有效的并且没有必要做唯一性检查时就可以操作。

下面是操作步骤:

  1. 用需要的表结构创建一张表,但不包括索引。
  2. 载入数据到表中以构建.MYD文件。
  3. 按照需要的结构创建另外一张空表,这次要包含索引。这会创建需要的.frm和.MYI文件。
  4. 获取读锁并刷新表。
  5. 重命名第二张表的.frm和.MYI文件,让MySQL认为是第一张表文件。
  6. 释放读锁。
  7. 使用REPAIR TABLE来重建表的索引。该操作会通过排序来构建所有索引,包括唯一索引。

这个操作步骤对大表来说会快很多。