最推荐停库迁移整个datadir到SSD:干净安全、无引擎限制、兼容所有MySQL版本;需校验挂载权限、更新my.cnf路径、处理SELinux、验证配置后启动。

直接把 datadir 整体迁到 SSD 是最简单、最安全的方案,但必须停库操作;若只想迁移部分表(尤其是大日志表、冷数据表),InnoDB 表空间机制才是正解,别碰 DATA DIRECTORY 或符号链接。
停库迁移整个 datadir 到 SSD 挂载点
这是生产环境最推荐的方式:干净、无引擎限制、无需改表结构、兼容所有 MySQL 版本(5.7+ / 8.0+)。
- 确认 SSD 已挂载且有写权限:
df -h看目标路径(如/ssd/mysql)是否就绪,文件系统建议用xfs(对大文件和并发 IO 更稳) - 停 MySQL:
systemctl stop mysql(或mysqld_safe --shutdown) - 复制数据目录(保留权限):
rsync -avp /var/lib/mysql/ /ssd/mysql/(注意末尾斜杠!) - 修改
/etc/my.cnf中的datadir和socket路径,同时检查pid-file、log-error、log_bin等路径是否仍指向旧位置——它们也得一并挪过去或更新 - SELinux 用户额外执行:
chcon -R --reference=/var/lib/mysql /ssd/mysql,否则启动报错“Permission denied” - 启动前验证配置:
mysqld --defaults-file=/etc/my.cnf --validate-config
只迁移单个 InnoDB 表到 SSD:用独立表空间 + ALTER TABLE … TABLESPACE
适用于已有大表想“热切”到新盘,不中断服务(需 MySQL 5.7.6+,且 innodb_file_per_table=ON,默认已开)。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 先在 SSD 上创建通用表空间:
CREATE TABLESPACE ts_ssd ADD DATAFILE '/ssd/mysql/ts_ssd.ibd' ENGINE=InnoDB; - 迁移表(自动拷贝 .ibd + 更新元数据):
ALTER TABLE logs TABLESPACE ts_ssd; - 执行后原
/var/lib/mysql/dbname/logs.ibd会被移走,/ssd/mysql/ts_ssd.ibd成为唯一物理文件;.frm或.sdi仍留在原datadir下,不影响使用 - 注意:该操作会加
SX锁,阻塞写入但允许读;若表太大,迁移过程可能耗时数分钟,期间SHOW PROCESSLIST显示 “copy to tmp table” - 迁移后查
INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES,确认NAME列对应表名,SPACE_TYPE为general,FILE_FORMAT不为空
为什么别用 DATA DIRECTORY 语法?
DATA DIRECTORY 看起来方便,但它对 InnoDB 表无效(MySQL 8.0+ 直接忽略该子句,静默降级为默认位置),仅 MyISAM 支持——而 MyISAM 在现代 MySQL 中早已弃用,不支持事务、行锁、崩溃恢复。
- 你写
CREATE TABLE t1 (...) ENGINE=InnoDB DATA DIRECTORY='/ssd/data',MySQL 会照常建表,但物理文件仍在原datadir下,只多生成一个t1.isl文件(里面是路径字符串,完全不被 InnoDB 引擎读取) - 试图用它迁移已有表?
ALTER TABLE t1 DATA DIRECTORY='/ssd/data'会报错ERROR 1064 (42000),语法不被支持 - 即使 MyISAM 场景下用了,也绕不开文件权限、SELinux、AppArmor 等问题,且无法与 GTID/MGR 集群协同
迁移后必须调的三个 I/O 参数
SSD 不是插上就快——不调参,I/O 能力可能只发挥出 30%。
-
innodb_io_capacity:设为 SSD 实测随机写 IOPS × 0.75(例如 fio 测出 100K → 设75000),不是固定填 2000 或 10000 -
innodb_buffer_pool_size:按free -h的available值 × 0.7 设置,别贪大;设完检查Innodb_buffer_pool_wait_free是否持续 > 0 -
innodb_log_file_size:总大小(innodb_log_files_in_group × innodb_log_file_size)控制在innodb_buffer_pool_size × 0.25左右,比如 Pool=20G → 日志总和≈5G;调大必须停库删旧ib_logfile*,否则启动失败
真正容易被忽略的是:迁移后没关 Linux I/O 调度器。NVMe 盘必须设 elevator=none,SATA SSD 用 deadline;不关的话,IO 延迟抖动、吞吐卡在 60% 以下,性能优化全白做。

















