
Windows 和 Linux 的 MySQL 数据目录结构差异导致直接拷贝失败
MySQL 在 Windows 和 Linux 下默认使用不同的文件路径分隔符、大小写敏感策略和权限模型,直接复制 data/ 目录几乎必然报错——比如启动时卡在 mysqld: Can't find file: './mysql/plugin.frm',或表无法打开。根本原因不是数据损坏,而是系统层面对文件名、路径、权限的解释不一致。
- Linux 默认对数据库名、表名大小写敏感(取决于
lower_case_table_names配置),Windows 默认不敏感;若原库含大写字母表名,迁移到 Linux 后可能找不到 - Windows 下
data/里是mydb/+mytable.frm+mytable.ibd,Linux 若用默认配置(lower_case_table_names=0)会严格区分大小写,而 mysqld 服务启动时按小写路径去读,自然失败 - 直接拷贝的
ibdata1和日志文件(ib_logfile*)在跨平台后无法复用,必须重建
用 mysqldump 导出再导入是最稳妥的跨平台迁移方式
绕过文件系统差异,只迁移逻辑结构和数据,兼容性最高。关键不在“能不能导”,而在“怎么导才不出错”。
- 导出时务必加
--single-transaction(InnoDB 表)或--lock-tables=false(MyISAM),否则 Windows 上锁表可能阻塞业务,且 Linux 导入时容易因锁超时失败 - 显式指定字符集:
mysqldump --default-character-set=utf8mb4 -u root -p mydb > mydb.sql,避免 Windows 默认cp1252与 Linux 默认utf8mb4不一致导致乱码 - 导入前确认目标 MySQL 的
sql_mode与源库一致(尤其注意STRICT_TRANS_TABLES),否则可能因字段长度超限或空值插入失败 - 导入命令别用
source mydb.sql进 MySQL 客户端——大文件易中断;改用mysql -u root -p mydb ,更稳定
迁移后必须检查 lower_case_table_names 配置
这是最容易被跳过的致命环节。该值一旦设错,表能创建、能查,但后续任何 DDL(如 ALTER TABLE)或备份脚本都可能静默失败。
- Linux 上必须在
my.cnf的[mysqld]段落中显式设置:lower_case_table_names=1(推荐),或=2;不能留空或注释掉 - 该参数是只读的:修改后必须删除
data/目录下的所有ibdata1、ib_logfile*和mysql/子目录(保留mysql.sock所在目录结构),再初始化数据目录(mysqld --initialize或mysqld --initialize-insecure) - 验证方法:建一个含大写字母的表
CREATE TABLE TestTable (id INT),然后用小写查SHOW TABLES LIKE 'testtable';—— 应该能返回结果才算生效
二进制日志和主从配置需重置,不能复用旧文件
Windows 上生成的 mysql-bin.000001 及 mysql-bin.index 在 Linux 上无法被识别为有效 binlog,强行指定会导致启动失败或复制断裂。
- 迁移后首次启动前,清空
log_bin相关配置项(如log_bin、binlog_do_db),先让服务起来;再通过SET GLOBAL sql_log_bin = OFF;临时关闭日志,导入完数据后再启用 - 如果原 Windows 是主库,新 Linux 要当主库用,必须执行
RESET MASTER;清除旧 binlog 索引,并用SHOW MASTER STATUS;获取新起始位置 - 从库同步时,
CHANGE MASTER TO的MASTER_LOG_FILE和MASTER_LOG_POS必须来自新 Linux 主库的SHOW MASTER STATUS输出,绝不能沿用 Windows 的旧值
lower_case_table_names 和 sql_mode,它们不会报错,但会让后续维护变成定时炸弹。


















