真正能落地的批量迁移只有两种路径:小表用ALTER TABLE手动拼语句,大表必须上pt-online-schema-change;前者需加反引号和WHERE过滤防误改,后者须确认主键、无触发器、权限完整及主从延迟为0。

不能靠“快速”二字跳过锁表和磁盘风险——真正能落地的批量迁移,只有两种路径:小表用 ALTER TABLE 手动拼语句,大表必须上 pt-online-schema-change。
生成可执行的 ALTER TABLE 语句要加反引号和 WHERE 过滤
直接在 phpMyAdmin 或 MySQL 客户端里运行 SELECT 拼接语句,是最常用也最可控的起步方式。但漏掉两个细节就会报错或改错表:
-
TABLE_NAME必须用反引号包裹,否则表名含短横线(如user-log)或关键字(如order)时会语法错误 -
WHERE条件必须明确限定数据库名和引擎类型,否则可能跨库误改系统表:SELECT CONCAT('ALTER TABLE `', table_name, '` ENGINE=InnoDB;') FROM information_schema.tables WHERE table_schema = 'your_db' AND engine = 'MyISAM'; - 执行前先用
SELECT table_name, engine FROM information_schema.tables WHERE table_schema = 'your_db' AND engine = 'MyISAM';看一眼实际有哪些表,别信“应该就这几个”
大表(>1GB 或百万行)执行 ALTER TABLE 就是主动制造故障
MySQL 8.0 仍强制走 COPY 算法,不是“准备中”,而是真正在 copy to tmp table。这个过程会:
- 持有 MDL 写锁,所有
INSERT/UPDATE/DELETE全部阻塞,SELECT在 RR 隔离级别下也可能被卡住 - 磁盘空间占用翻倍:旧表
.MYD/.MYI+ 新表.ibd+ redo/undo 临时文件,10GB 表至少要留 25GB 空闲 - 主从延迟飙升:从库回放该 DDL 时同样锁表,
Seconds_Behind_Master可能跳到几小时 - 加
LOCK=NONE也没用——MySQL 会自动降级为LOCK=EXCLUSIVE,引擎切换本身不支持无锁
pt-online-schema-change 不是“一键工具”,四件事没确认就跑必失败
它靠触发器双写维持一致性,环境稍有偏差就中断或丢数据。上线前必须人工确认:
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
- 目标表是否有主键或唯一非空索引?没有就报错
This table has no primary key or unique index - 是否已关闭 FULLTEXT 索引?
pt-osc不支持 MyISAM 的全文索引迁移,必须先DROP INDEX -
innodb_file_per_table是否为ON?关着的话所有新表都挤进ibdata1,后续无法收缩 - 主从延迟是否为 0?
Seconds_Behind_Master != 0会导致影子表数据滞后,最终数据不一致
转换后不调参、不校验,等于白干
引擎变了,配置和行为必须同步变,否则性能可能更差:
- 立刻调大
innodb_buffer_pool_size(建议设为物理内存的 50%–75%),同时把key_buffer_size降到 32M 左右 - 用
COUNT(*)对比原表和新表行数,必须在相同事务隔离级别(推荐REPEATABLE READ)下执行 - 业务 SQL 要重测:特别是
MATCH AGAINST全文查询,InnoDB 分词逻辑、停用词、最小词长都和 MyISAM 不同 - 旧的
.MYD/.MYI文件不会自动删,确认新表数据一致后再手动清理,否则磁盘悄悄涨满
最常被忽略的是:迁移不是“改完引擎就结束”,而是从查表、拼语句、选工具、调参数到验证 SQL 行为的完整链路。任何一个环节跳步,都会在凌晨三点收到告警。










