改了datadir却启动失败,主因是Ubuntu默认启用的AppArmor拦截,需编辑/etc/apparmor.d/usr.sbin.mysqld添加新路径规则(如/mnt/data/mysql/ r,/mnt/data/mysql/** rwk,),再执行sudo systemctl reload apparmor并验证生效。

为什么改了 datadir 却启动失败?AppArmor 在拦你
MySQL 服务在 Ubuntu 上无法启动,报错 InnoDB: Operating system error number 13 或日志里反复出现 Permission denied,基本可以断定是 AppArmor 拦住了。它不是“可选安全模块”,而是 Ubuntu 22.04/20.04 默认启用的强制访问控制机制——哪怕你把 datadir 改对了、权限 chown -R mysql:mysql 也设好了,只要 AppArmor 策略没更新,MySQL 进程就无权读写新路径。
/etc/apparmor.d/usr.sbin.mysqld 文件怎么改才不翻车
这个文件是 MySQL 的 AppArmor 策略定义,必须手动编辑。关键不是“加两行”,而是改得精准、不破坏原有规则:
- 不要直接删除或注释掉旧路径的规则(比如
/var/lib/mysql/ r,),先保留,等确认新路径完全跑通后再处理 - 新增规则必须和原格式严格一致:末尾带空格 + 逗号 + 换行,例如:
/mnt/data/mysql/ r,/mnt/data/mysql/** rwk, - 路径末尾的
/不能漏,**表示递归匹配子目录和文件,r是读,w是写,k是锁(InnoDB 必需) - 如果新路径含空格或特殊字符(如
/my data/mysql),必须用双引号包裹:"/my data/mysql/" r,
改完策略后,reload 还是 restart?别 reload 错对象
AppArmor 策略变更后,必须让内核重新加载策略,但操作对象不是 apparmor 服务本身(它没有 restart/reload 单元),而是调用 aa-reload 或 systemctl 命令:
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
- 推荐执行:
sudo systemctl reload apparmor(Ubuntu 22.04+ 稳定支持) - 备选方案:
sudo aa-reload(更底层,兼容性更好) - 绝对不要运行
sudo systemctl restart apparmor—— 这个服务没有 restart 动作,会报错且无实际效果 - reload 完成后,检查是否生效:
sudo aa-status | grep mysqld,输出中应包含你新加的路径
容易被忽略的三个硬性条件
即使 AppArmor 配置正确,MySQL 仍可能起不来,因为还有三个依赖项必须同步满足:
-
mysqld进程必须由 systemd 启动(而非手工mysqld --user=mysql ...),否则 AppArmor 策略不生效 - 新数据目录的磁盘必须已挂载且在线;若挂载点是
/mnt/data,请确认mount | grep /mnt/data有输出 - SELinux 在 Ubuntu 上默认未启用,不用管;但如果你启用了(极少见),它会和 AppArmor 冲突,此时应禁用 SELinux 而非调试双重策略
AppArmor 不是“配一次就完事”的开关,它是路径级的硬隔离。每次迁移数据目录、添加新日志路径(如 slow_query_log_file)、甚至配置 secure_file_priv,都得同步更新策略——漏掉任意一个路径,MySQL 就会在某个看似无关的操作上突然报错。

















