最稳妥的跨服务器迁移方式是用mysqldump导出再导入;需加--single-transaction保证innodb一致性,混myisam则用--lock-all-tables,并加上--routines--triggers--events;避免--all-databases;导入前须手动建库并指定与源库一致的字符集和排序规则。

直接用 mysqldump 导出再导入,是最稳妥、兼容性最强的跨服务器迁移方式。物理拷贝(如直接复制 /var/lib/mysql/xxx_db)在绝大多数生产场景下不推荐——版本稍有差异、配置没对齐、文件系统不一致,就启动失败。
导出时必须加 --single-transaction
这是保证 InnoDB 表数据一致性的关键。不加它,mysqldump 可能读到中间态数据,尤其在业务写入活跃时。
- 仅对 InnoDB 有效;如果库中混有 MyISAM 表,得改用
--lock-all-tables - 务必同时加上
--routines --triggers --events,否则存储过程、触发器、定时事件全丢 - 避免用
--all-databases:会把mysql系统库也导出,导入后可能覆盖目标库权限配置 - 导出命令示例:
mysqldump -h192.168.1.100 -uroot -pMyPass123 --single-transaction --routines --triggers myapp_db > myapp_db.sql
导入前要手动建库并指定字符集
MySQL 8.0 默认字符集是 utf8mb4_0900_ai_ci,但很多旧库用的是 utf8mb4_general_ci 或 utf8mb4_unicode_ci。不显式声明,导入后字段乱码或排序异常。
- 先在目标服务器执行:
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;(字符集需和源库一致) - 导入时不要用
USE切库,而是直接指定库名:mysql -h127.0.0.1 -uroot -pMyPass123 myapp_db - 如果导入卡住或报错
ERROR 1835 (HY000),大概率是源库用了utf8而目标库默认utf8mb4,需在导入命令前加--default-character-set=utf8
rsync 拷贝数据目录几乎必然失败
即使你停掉了源库,rsync 直接同步 /var/lib/mysql/ 仍极大概率启动失败。InnoDB 对页大小、校验算法、文件格式极其敏感。
- 常见报错:
Tablespace is missing for table、InnoDB: Unsupported redo log format、Can't start server: Permission denied - 必须满足全部条件才可能成功:MySQL 版本完全一致 +
innodb_page_size相同 +innodb_checksum_algorithm相同 +lower_case_table_names设置一致 + 文件系统支持硬链接(XFS/ext4) - 属主权限只是表象问题,真正拦路虎是内核级参数不匹配。别为省几小时时间赌这个
真正容易被忽略的点是:迁移后应用连接池里的旧连接不会自动断开,得重启应用或清空连接池;另外 information_schema 和 performance_schema 不属于用户库,无需、也不能迁移——它们由 MySQL 实例自动生成。











