简介:在MySQL数据库管理中,将数据文件夹从系统默认位置迁移至独立分区,是保障数据安全、缓解存储压力、优化磁盘性能的常见需求。这份PDF教程面向Linux服务器运维人员与MySQL管理员,系统讲解了将默认的数据库数据目录迁移至新分区的完整流程。内容不仅涵盖停止服务、移动目录、修改MySQL主配置文件,也细致说明了为何使用移动命令而非复制命令,以及如何保留SELinux属性、同步更新PHP连接配置中的套接字路径,并在全部调整后重启验证。教程还指出了迁移过程中容易忽略的权限与连接故障点,帮助读者一次成功。资源为单个PDF文档,压缩包仅37KB,轻量精炼,目前已获得1867人学习下载。步骤清晰、命令明确,适合需要在不熟悉安全增强环境下稳妥迁移数据库目录的中级运维人员。
1. 把 MySQL 的 data 文件夹搬到新磁盘:从磁盘告警开始的一次迁移
半夜收到磁盘空间告警,系统盘快满,MySQL 的数据目录占了几十个 G,业务又不能长时间停——这是很多人第一次接触到「MySQL数据库迁移data文件夹位置」这个操作的典型背景。表面上看就是停服务、拷贝文件、改配置、重启四步,但真正让新手翻车的地方全在细节里:拷贝时权限和隐藏文件丢没丢、SELinux 和 AppArmor 拦不拦、路径格式写没写对、启动失败后有没有后悔药。无论 MySQL 5.7.44 还是 8.0 LTS,这套流程都适用,差异只在日志路径和配置文件名上。适合自己维护 MySQL 的运维和全栈开发,也适合 Windows 开发机上想把 MySQL 从 C 盘挪到 D 盘的人。
下面从迁移前的选型开始,把每一步命令和参数讲透,最后给一份避坑清单。
2. 迁移前先摸清家底:定位 data 目录与选型
2.1 用一条 SQL 和一份配置文件确认当前数据目录
不要靠记忆里的默认路径下结论。机器上可能装过多个 MySQL,或者 my.ini / my.cnf 里早就被改过 datadir。最可靠的方式是先登录 MySQL 看运行时到底用的哪个路径:
-- 直接输出当前实例实际使用的数据目录 SELECT @@datadir; -- 想看得更全就查所有路径相关变量 SHOW VARIABLES WHERE Variable_name IN ('datadir','log_bin','log_error');逻辑说明:@@datadir是全局系统变量,MySQL 启动时根据配置文件解析后写入,返回的是服务真正在用的路径,而不是你猜的路径。这条 SQL 属于 MySQL 数据库常用命令里不起眼但关键时刻最救命的一条。后半句把log_bin、log_error一起查出来,是因为迁移 datadir 时这些文件可能也在旧目录里,提前看清才能决定是一起搬还是单独迁移。
Linux 上还要确认配置文件读取顺序,防止改了一个文件、结果被另一个 include 进来的文件覆盖:
# 查看 mysqld 会按什么顺序读取配置文件 mysqld --verbose --help | grep -A 1 "Default options" # 直接输出 [mysqld] 组解析后的 datadir,包含 include 的文件 my_print_defaults mysqld | grep datadir参数说明:--verbose --help打印的是编译默认值加环境推导结果,grep 出来能看到 /etc/my.cnf、/etc/mysql/my.cnf、~/.my.cnf 这些候选文件的读取顺序。my_print_defaults更实用,它会连 include 的文件一起解析输出最终值。CentOS 系默认往 /etc/my.cnf 写,Ubuntu 系拆成 /etc/mysql/mysql.conf.d/mysqld.cnf,改哪个取决于实际生效的优先级。
Windows 上,安装版 MySQL 的配置文件默认在C:\ProgramData\MySQL\MySQL Server 8.0\my.ini,注意 ProgramData 是隐藏目录,资源管理器里直接看不到。服务名和路径可以在 services.msc 里双击 MySQL 服务看「可执行文件路径」,也可以在命令行用sc qc MySQL80查。总之,不要凭安装教程里的截图记路径,要以服务实际指向为准。
这里要特别提醒一句:datadir 是一个目录树,里面不只是业务库文件夹。包括每个库自己的子目录(5.7 起每张 InnoDB 表一个 .ibd 文件)、共享表空间 ibdata1、undo 表空间、redo 日志(8.0.30 之后在#innodb_redo目录,5.7 是 ib_logfile0/1)、auto.cnf(保存 server-uuid)、以及默认落在 datadir 下的 binlog。迁移的对象是"整个 datadir 目录树",不是把某个业务库目录搬走就完事,这也是后面避坑章节里最高频的误区。
2.2 整目录搬迁还是软链接:两条路线各有边界
常见的从业方案有两条,选哪条取决于你能接受多少停机时间、以及后续想不想长期维护。
路线 A:改配置文件里的 datadir 指向新目录。优点是一劳永逸,目录结构清楚,备份脚本、监控告警都直接对应新路径;缺点是改完配置后的第一次启动有风险,SELinux、AppArmor、权限任何一环出问题都起不来。正式迁移、换盘、长期维护,我默认走这条。
路线 B:配置不动,把数据搬到新盘,在原 datadir 位置建一个指向新盘的符号链接。优点是失败回滚极快——删掉软链接、原目录就露出来了,适合磁盘快满、想先腾空间再找时间正式迁移的场景;缺点是有的 MySQL 版本对 datadir 使用符号链接有限制,而且备份程序如果解析真实路径会备份到两份,监控告警也容易绕晕。我一般只把软链接当"临时手段",做完后会在下一个维护窗口切到路线 A。
还有一条容易混淆的路:Docker 里装的 MySQL。容器内改 datadir 配置没有意义,正确做法是挂载宿主机目录到容器的 /var/lib/mysql,或者重建容器时指定数据卷。网上 docker 安装 mysql 失败的求助帖,本质就是没搞清容器内数据目录和宿主机数据目录的关系,这个场景跟本标题的"改配置文件"流程不是一回事。
另外,如果你的停机时间窗口很短,停服搬迁这种方式可能满足不了要求。有一种思路是"不搬文件、直接备份恢复":用 Percona XtraBackup 或逻辑备份把数据导到新目录的实例,这条路线可以在线做,但本质是备份恢复而不是目录迁移,验证成本和配置成本都更高。本文默认讲停服搬迁,对停机时间有硬指标的人,单独去评估那类方案更合适。
2.3 新目录的容量、文件系统与 I/O 检查
迁移前花十分钟做四项检查,能省掉迁移后的一堆麻烦。我习惯用下面这组命令:
| 检查项 | 常用命令 | 关注点 |
|---|---|---|
| 当前数据总量 | du -sh /var/lib/mysql | 看整个 datadir,不是只看业务库 |
| 新盘剩余空间 | df -h /data | 预留至少 1.5~2 倍当前体积 |
| inode 余量 | df -i /data | 表多、碎片多时 inode 容易成为隐藏瓶颈 |
| 文件系统类型 | stat -f /data | ext4 / xfs 优先,FAT 类文件系统不能放数据库 |
第一项du的坑在于很多人只统计了业务库目录,忘了 ibdata1 和 binlog。第二项容量预估不能只看当前占用,还要看增长速度:查一下 binlog 目录大小和最近每月的增长量,或者用information_schema.tables统计 data_length 加 index_length 的月变化,新盘至少预留当前体积的两倍,增长快的业务可以按三倍留。
第三项df -i容易被忽略。MySQL 数据目录的文件数常常上万,尤其 5.7 之后每张表一个 .ibd,小表一多 inode 消耗非常快,inode 使用率超过 80% 就要警惕,否则迁过去没多久就报 "No space left on device",但df -h看空间明明还有。
第四项和性能有关。迁移同时也是换 I/O 环境,如果新盘是机械盘、移动硬盘或者 NFS 挂载,事务提交延迟会直接变差,因为 InnoDB 的 redo 写入和 binlog 落盘都吃 fsync。有条件的话把 log-bin 单独指到另一块高速盘,datadir 放数据盘,两者分离是生产环境的常规做法。迁移完成后跑一个简单的 sysbench 对比迁移前的延迟,比盯着玄学体感靠谱得多。
提示:数据盘挂载选项不要乱加激进优化,ext4/xfs 的默认挂载参数对 MySQL 已经够用,折腾挂载参数只会让排障更困难。
3. Linux 下迁移 data 目录:停服、rsync、改配置三步走
3.1 先停服务,确认干净的 shutdown,不要直接 kill -9
迁移的前提是数据文件处于一致状态。最稳的做法是让 mysqld 自己走完正常关闭流程:InnoDB 会在 shutdown 时做 checkpoint,把 redo 里的变更落到数据文件,清理临时表空间,然后才退出。这样拷贝出去的目录是干净一致的,到新盘启动时不需要走崩溃恢复。反过来,直接 kill -9 或systemctl kill跳过 shutdown,拷贝过去的文件大概率要在启动时做 crash recovery,运气好只是启动变慢,运气不好直接报表损坏。
# 用 systemd 停服务,发行版默认服务名是 mysqld 或 mysql systemctl stop mysqld # 确认服务状态变成 inactive,并且没有残留进程 systemctl status mysqld ps aux | grep mysqld参数说明:systemctl status输出里 Active: inactive (dead) 才算停干净;第二次ps是为了防止有多实例场景或者 systemd 之外手动拉起的 mysqld_safe 还在跑。老一点的发行版用service mysql stop,效果等价。如果停了很久还在 shutting down,不要立刻 kill -9,先看 error log 是不是在刷页或做长时间 checkpoint,给个几十秒耐心;实在卡死再考虑强制结束,但要意识到"非干净关闭"这个事实,并做好启动时崩溃恢复的心理准备。
停完看日志,确认关闭过程正常:
# 正常关闭的标志:日志尾部出现 Shutdown complete tail -n 50 /var/log/mysql/error.log日志路径因发行版和安装方式而异:Ubuntu 的 apt 包是 /var/log/mysql/error.log,CentOS 的 rpm 包是 /var/log/mysqld.log,源码编译或二进制包装的可能在你指定的 log-error 路径。看到 "Shutdown complete" 才可以继续,看不到就说明服务还没干净退出,回去查进程。
3.2 用 rsync 搬整个 datadir 并做增量校验
拷贝这一步,核心诉求有三个:文件权限和属主不丢、大目录中断了能续、搬完能验证一致性。rsync 一条命令全解决,这也是我不用 cp -r 的原因——cp 到一半断了只能重来,且默认不保证属主和权限原样保留。
# 先建目标目录并给对属主 mkdir -p /data/mysql chown mysql:mysql /data/mysql # 归档模式拷贝,保留权限、属主、时间戳,显示进度 rsync -av --progress /var/lib/mysql/ /data/mysql/ # 再跑一次 dry-run,确认两边没有差异 rsync -avn /var/lib/mysql/ /data/mysql/逻辑说明:注意源路径末尾的斜杠/var/lib/mysql/,带斜杠表示"拷贝目录里的内容",不带斜杠则会把 mysql 这个目录本身嵌套进目标路径。rsync -a等价于-rlptgoD,把符号链接、权限、属主、时间戳都保留,这正是数据目录最需要的。第二次 dry-run 的-n参数只列出将要传输的文件,正常情况下输出为空;如果还有输出,说明第一次拷贝中途有文件变化或漏了目录,补齐后再继续。
参数说明:--progress在几十 G 的数据量上能看到单文件进度,方便估算剩余时间;不要加-z压缩,数据库文件基本都是紧凑的二进制,压缩收益低还吃 CPU。源盘和目标盘在宿主机本地时,rsync 直接走本地路径,不用画蛇添足走 ssh。拷贝完成后做两个抽查:ls -l /data/mysql/auto.cnf看属主是不是 mysql:mysql,ls -la /data/mysql/看隐藏文件都在不在。漏一个,后面启动就可能翻车,这是血泪经验。
3.3 改 my.cnf 的 datadir,别漏了 SELinux 和 AppArmor
配置文件这一步,最常见的错误是改错文件。CentOS/RHEL 系默认读 /etc/my.cnf,Ubuntu/Debian 系拆成 /etc/mysql/my.cnf 加 /etc/mysql/mysql.conf.d/mysqld.cnf,后者通过 include 机制合并。建议先用 2.1 小节的my_print_defaults确认实际生效文件再动手:
# 在 [mysqld] 段里加一行,指向新目录 [mysqld] datadir=/data/mysql改完先校验语法再启动,MySQL 8.0.16 以后自带配置校验命令:
mysqld --validate-config这个参数只解析配置文件、不启动实例,语法或密钥文件错误会在启动前暴露,输出为空说明配置通过。
CentOS/RHEL 下如果开了 SELinux,光改配置不够,要给新路径打数据目录的上下文标签:
# 给 /data/mysql 及其子目录打上 mysqld_db_t 标签 semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" restorecon -Rv /data/mysqlUbuntu 下则是 AppArmor,MySQL 的 profile 默认只放行 /var/lib/mysql:
# 编辑 /etc/apparmor.d/usr.sbin.mysqld,在规则里加新路径 # /data/mysql/ rw, # 然后重载 profile 使其生效 apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld逻辑说明:这两步不是可选项。少了它们,MySQL 启动日志里会出现 Permission denied,但目录权限和属主明明正确,新手很容易陷入玄学排查。区分方法很简单:先看 audit.log(SELinux)或aa-status(AppArmor)有没有拦截记录,再用setenforce 0临时放行验证"是不是 SELinux 的锅",确认后把正规规则写回去。
注意:setenforce 0 只适合临时定位问题,迁移验收前一定要把 fcontext 规则写回去,否则系统重启后 SELinux 恢复 enforcing,业务会被再一次打断。
3.4 启动、看日志、核对新的 datadir
启动这一步别急着庆祝,按顺序验证:
systemctl start mysqld sleep 5 systemctl status mysqld tail -n 50 /var/log/mysql/error.log-- 确认 MySQL 实际使用的数据目录 SELECT @@datadir;逻辑说明:@@datadir返回服务真正在用的路径,和配置一致才算数据目录切过去了。启动失败时优先看 error log 末尾三四十行,而不是反复 restart 碰运气。error log 不是黑匣子,每次失败都有明确线索。常见报错归个类:
| 日志关键字 | 大概率原因 | 排查方向 |
|---|---|---|
| Permission denied | 属主/权限不对,或 SELinux/AppArmor 拦截 | 查 audit.log、aa-status、ls -l |
| Can't create/write to file | 新目录写权限不足或盘已满 | df -h、touch 测试 |
| Can't find file / unknown variable | datadir 没生效或路径拼写错误 | my_print_defaults 和 @@datadir 对比 |
| Table doesn't exist + crashed | 拷贝时源数据不干净 | 回退重做干净 shutdown,再做一次拷贝 |
这套对照表来自我处理过的多次迁移排障,方向先对上,后面就好办了。
4. Windows 下迁移 data 目录:服务、robocopy、my.ini 三件套
4.1 用 net stop 停服务,确认 mysqld 进程真的退出
Windows 10 上装 MySQL 很简单,但装完数据目录默认在 C 盘,用一段时间 C 盘就红,于是把 data 目录挪到 D 盘成了刚需。这一节第一个坑是服务名:MySQL 8.0 安装版的服务名默认是 MySQL80,5.7 zip 解压版手动注册时常写成 mysql。网上 mysql 安装配置教程到"服务启动成功"就结束了,没人提醒你迁移时要按 services.msc 里真实的服务名操作:
:: 停掉 MySQL 服务,服务名以 services.msc 里显示为准 net stop MySQL80 :: 确认进程真的退出,没有残留 mysqld.exe tasklist | findstr mysqld参数说明:net stop之后 tasklist 应该没有任何 mysqld 输出。如果还有进程,说明存在第二个实例、或者服务停在了 stopping 状态,这时候拷数据等于在文件还在被写入时拍快照,数据一致性无法保证。很多人卡在"net start mysql 服务无法启动",十有八九就是上次迁移后配置和实际路径对不上,或者服务账户对新目录没有权限,这两个问题后面的小节都会碰到。
停服务前,先确认这台机器上没有其他进程依赖这个 MySQL。本地开发机可能挂着 Navicat 或 IDE 的连接池,它们不会锁文件,但迁移期间连着的客户端会产生大量重连日志,干扰你对 error log 的判断。我一般会把计划任务里调用 mysql 的脚本先禁用,免得迁移中途一个 mysqldump 又拉起连接。停完顺手确认端口释放:netstat -ano | findstr 3306,端口还被占说明有别的进程在监听,查清楚再动数据。
4.2 用 robocopy 搬数据,别用资源管理器拖拽
拷贝大目录,资源管理器拖拽是最不靠谱的:中途断开没有续传、权限属性可能丢失、几百行输出还没法定位问题。robocopy 是 Windows 自带的标准工具,对应 Linux 下 rsync 的地位:
robocopy "C:\ProgramData\MySQL\MySQL Server 8.0\Data" "D:\MySQLData" /E /COPYALL /R:3 /W:10 /MT:16参数说明:/E拷贝所有子目录包括空目录;/COPYALL复制文件所有属性,包括 NTFS 权限、所有者、时间戳,对应 rsync 的-a;/R:3和/W:10是单个文件复制失败时重试 3 次、每次等待 10 秒,解决文件临时被占用的问题;/MT:16用 16 个线程并行拷贝,数据量大时提速明显,机器配置差就降到/MT:8避免 IO 饱和。
robocopy 的退出码和普通命令不一样,0 到 7 都代表成功,8 及以上才是失败。脚本判断别写成if errorlevel 1就走失败分支,那是 Windows 的老坑。校验方式也是再跑一次:
:: /L 只列出将要复制的文件,不真正复制;输出为空说明两边一致 robocopy "C:\ProgramData\MySQL\MySQL Server 8.0\Data" "D:\MySQLData" /E /L也可以用 PowerShell 对比文件数:(Get-ChildItem -Path 'D:\MySQLData' -Recurse -File).Count,两边数量对得上才算完整。robocopy 的/XD、/XF排除参数在特殊场景有用,但我的建议是第一次先全量搬,确认能启动后再做归整,别在迁移过程中顺手做文件治理,一次只干一件事。
4.3 my.ini 修改:反斜杠转义与服务账户权限
my.ini 的位置在安装版里是C:\ProgramData\MySQL\MySQL Server 8.0\my.ini,zip 解压版在你解压目录下。改 datadir 时,路径分隔符我统一建议用正斜杠:
[mysqld] datadir=D:/MySQLData逻辑说明:my.ini 是 INI 格式,MySQL 在 Windows 下解析路径时,反斜杠在某些场景会被当作转义符处理,D:\MySQLData里的\M可能变成不可见字符,导致启动报"找不到路径"。写成D:/MySQLData是 Windows 完全支持、又没有任何转义歧义的写法,这也是网上 mysql 安装教程很少讲到的细节。
改完配置,还有一个 Windows 专属大坑:权限。安装版的 MySQL 服务默认以 NETWORK SERVICE 账户运行,这个账户对旧数据目录有权限,但你新建的D:\MySQLData默认只有 Administrators 有权限,服务账户碰不到新目录,启动时立刻失败:
:: 给 NETWORK SERVICE 授予新目录的完全控制权,/T 递归 icacls "D:\MySQLData" /grant "NETWORK SERVICE:(OI)(CI)F" /T参数说明:(OI)(CI)F表示对目录内现有对象和未来创建的对象都授予完全控制权限,/T递归到子目录。如果服务在 services.msc 里配置成 LocalSystem 账户运行,就不用加 NETWORK SERVICE,改成给 Administrators 或 Users 授权即可。拿不准就双击服务看"登录"选项卡,按实际账户授权。
还有一个 Windows 独有的隐患:机器上装过多个 MySQL 实例时,每个实例读的 my.ini 可能不同。判断方式是用sc qc 服务名看-defaults-file参数指向哪个文件,改错 my.ini 会让另一个实例启动失败。改配置前先备份一份 my.ini,留一个.bak是最便宜的后悔药。
最后校验并启动:
:: 校验配置语法,8.0.16+ 支持 mysqld --validate-config :: 启动服务 net start MySQL80启动失败时,事件查看器里看到的 1067 错误只是笼统的"进程意外终止",真实原因全在数据目录下的主机名.err 文件里。如果 .err 文件也在旧目录,先去旧目录读日志——这就是为什么迁移时原目录和日志不要急着删。
5. 迁移避坑清单:5 个高频翻车现场
下面五条是我在多次迁移里踩过或帮人排查过的现场,按出现频率排序。
5.1 拷贝漏了隐藏文件,启动直接报 uuid 相关错误
现象:迁移完启动失败,error log 里出现 Failed to find valid data directory 或 server_uuid 相关报错,新目录里表文件明明都在。
原因:用 find + cp 按文件类型筛选拷贝,或者用文件管理器拖拽时隐藏文件没显示,auto.cnf(存 server-uuid)这类不显眼的小文件没过去。MySQL 启动时要读 server-uuid 确认实例身份,缺了就直接拒绝启动。
解决:只使用 rsync -a、robocopy /E /COPYALL、cp -a 这类整目录操作,不要按 *.ibd 或 *.frm 粒度去筛选。拷完先ls -la新目录,确认 auto.cnf、undo 等文件都在,再启动。这条看起来最简单,却是迁移报错里占比最高的原因之一。
5.2 Ubuntu 下目录权限明明对,启动依然是 Permission denied
现象:chown mysql:mysql 做了,权限 750 也给了,error log 依旧 Permission denied,ls 看文件一切正常。
原因:Ubuntu 的 MySQL 跑在 AppArmor 沙箱里,profile 文件 /etc/apparmor.d/usr.sbin.mysqld 只放行默认路径 /var/lib/mysql。新路径不在规则里,内核直接拒绝。
解决:编辑 profile 文件,在 data 规则附近加一行/data/mysql/ rw,,然后apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld重载。验证是否生效用aa-status看 mysqld profile。别用 chmod 777 或者aa-complain关掉整个防护,那是给自己埋雷。
5.3 CentOS 上配置没问题,SELinux 日志里全是 avc denied
现象:datadir 指对了、属主和权限都对,启动还是 Permission denied;查 /var/log/audit/audit.log,能看到 mysqld 对 /data/mysql 的 denied 记录。
原因:SELinux 的 mysqld_db_t 上下文只覆盖默认数据目录,新路径没有打标签,强制模式下访问被拦。
解决:semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?" && restorecon -Rv /data/mysql。临时验证可以用setenforce 0,确认是 SELinux 的问题后必须把 fcontext 规则写进去,否则重启机器后 SELinux 恢复 enforcing,迁移现场再次翻车。
5.4 Windows 的 my.ini 路径反斜杠被转义,服务起不来
现象:my.ini 里 datadir 明明写的是 D:\MySQLData,服务就是启动失败,日志里路径显示得诡异或报找不到目录。
原因:INI 解析时反斜杠被当成转义字符,\M被吃掉或变成奇怪字符,实际生效路径根本不是你以为的那个。
解决:统一写成D:/MySQLData,MySQL 在 Windows 下完全支持正斜杠,这是最省心的写法。快速自测:把 datadir 临时改成正斜杠试试能不能起来,能起就说明确实是反斜杠问题。启动后跑SELECT @@datadir确认实际生效路径,别只看 my.ini。
5.5 迁移完旧盘占用没降:只搬了业务库目录
现象:SELECT @@datadir已经指向新盘,但旧盘占用几乎没释放,新盘空间却在快速增长。
原因:datadir 是一个完整目录树,包含 ibdata1、undo、binlog、redo 这些公共文件。只把业务库的子目录搬走,或者 binlog 显式配置在旧路径,那么真正占空间的"大头"根本没动。
解决:迁移目标必须是整个 datadir 目录树,不是单个 schema 文件夹。迁移前用du -sh /var/lib/mysql看整个目录,再用du -sh /var/lib/mysql/*看"大头"分布,一眼能看出哪些文件决定了磁盘占用。启动后把log_bin_basename、log_error、slow_query_log_file、tmpdir全查一遍,确认这些"隐藏的文件"的实际落点。binlog 建议单独设置过期时间,避免新盘被日志灌满。
6. 迁移后的验证与回滚:给操作留一条后悔药
启动成功不代表迁移完成。我的固定动作是按顺序跑一套最小验证,SQL 长这样:
-- 1. 确认 datadir 生效 SELECT @@datadir; -- 2. 系统库和业务库都能访问 SHOW DATABASES; -- 3. 抽查几张核心业务表 SELECT COUNT(*) FROM yourdb.your_table;SQL 过了之后还有两道物理检查:error log 里不能出现 ERROR 级别,mysqlcheck 全库一致性检查跑一遍。业务侧找一个人写场景,insert 一条再查出来,体感比看日志直接。早年间我做迁移只看了个 @@datadir 就以为完事,结果业务第二天报错,才发现一张归档大表没搬全,回滚又无路可走,最后只能从备份恢复,白白折腾大半天。
回滚方案要在迁移之前就写好,而不是事后补救。我的习惯有两条:第一,原目录保留至少 72 小时,迁移期间和验证期间都别删;第二,把回滚命令写在记事本里,真出问题就停服改回 datadir 原路径再启动,十几秒回到迁移前状态。如果你担心改配置引入二次故障,还有更省事的思路:配置不动,数据搬到新盘后,在原 datadir 位置放一个指向新盘的软链接,出问题就删软链接把原目录露出来。这种"软链接托底"的做法在磁盘快满、没时间正式验收的场景里特别实用。
验证通过后,再观察至少一个业务低峰周期:磁盘增长曲线有没有异常、慢查询有没有变多、error log 有没有周期性报错。迁移不是一道命令的事,是一两天内的持续观察。现在我把"原目录保留 + 验证脚本先跑通 + 回滚命令前置"当成 datadir 操作的固定动作,这套习惯比任何迁移技巧都保险,希望帮到你。
本文还有配套的精品资源,点击获取