myisam表迁移不能依赖--single-transaction或物理拷贝,必须确保.frm、.myd、.myi三文件完整一致,停写后flush tables with read lock,严格校验权限与版本兼容性,并导入后执行repair table验证。

MyISAM 表不能像 InnoDB 那样靠 mysqldump 加 --single-transaction 保证一致性,也不能用物理拷贝直接“复制粘贴”——它看起来简单,实则极易损坏,尤其在没停服务或路径权限出错时。
MyISAM 表文件结构必须完整迁移
MyISAM 表由三个文件组成:.frm(表结构)、.MYD(数据)、.MYI(索引)。缺一不可,且文件名、大小、修改时间必须严格一致。任意一个文件损坏或不匹配,MySQL 启动后会报 Table 'db.table' doesn't exist 或 Incorrect file format。
- 确认源库已停止写入:执行
FLUSH TABLES WITH READ LOCK;,再SHOW OPEN TABLES WHERE In_use > 0;检查无活跃表锁才可继续 - 不要只拷
.MYD和.MYI:漏掉.frm会导致目标库无法识别表结构,哪怕文件存在也报错 - 目标服务器 MySQL 版本需兼容:MyISAM 在 MySQL 8.0 中仍支持,但部分旧字段类型(如
TINYTEXT的排序规则)可能因字符集配置不同而加载失败
符号链接方式风险极高,慎用
有人尝试用 ln -s 把 .MYD/.MYI 指向新磁盘,但这在 MySQL 8.0+ 默认被禁用(--skip-symbolic-links),且一旦路径权限不对、软链断裂或 SELinux 拦截,表直接不可用,错误日志里常出现 Can't find file: './db/table.frm' (errno: 13)。
- 若真要用符号链接,必须在
my.cnf显式开启:symbolic-links=ON(MySQL 5.7)或skip-symbolic-links=OFF(MySQL 8.0+) - 目标路径属主必须是
mysql:mysql,且目录不能有 world-writable 权限(如chmod 755可行,777会被 MySQL 拒绝加载) - 不建议跨文件系统做软链:XFS/ext4 上尚可,Btrfs/ZFS 因硬链接语义差异,极大概率导致数据读取错乱
逻辑导出导入仍是首选方案
对 MyISAM 表而言,mysqldump 虽慢,却是最稳妥的跨服务器迁移方式。它不依赖文件系统一致性,也不受 MySQL 版本微小差异影响,还能过滤、改写 SQL(比如替换数据库名、调整引擎)。
- 导出时加
--no-create-info如果目标库已建好表结构,避免重复建表失败 - 导入前手动执行
SET SESSION sql_mode='';,防止 MySQL 8.0+ 严格模式下因空值或默认值报错 - 大表导入卡住?改用
mysql --local-infile=1+LOAD DATA INFILE(需提前GRANT FILE ON *.* TO ...) - 别信 dump 文件里的
CREATE TABLE ... ENGINE=MyISAM—— 目标库若默认引擎是 InnoDB,必须显式指定ENGINE=MyISAM,否则表创建成功但行为异常
MyISAM 迁移真正的坑不在“怎么拷”,而在“怎么验证”。哪怕所有文件都复制过去、MySQL 也启动了,也要逐表执行 REPAIR TABLE db.table;,因为 MyISAM 没有崩溃恢复机制,一次异常关机就可能导致索引错位——这点很容易被忽略,直到某次查询突然返回空结果或乱序数据才暴露出来。











