MySQL启动报“Operation not permitted”主因是systemd安全策略(ProtectHome/ProtectSystem)、SELinux/AppArmor拦截或socket/pid路径不当,需依journalctl日志定位并针对性修复。
这通常不是 Linux 文件权限问题,而是 MySQL 8.0+ 默认启用了 systemd 的 ProtectHome=true 和 ProtectSystem=full 安全策略,导致 mysqld 进程无法访问 /var/lib/mysql 或写入 socket、pid 文件。
sudo journalctl -u mysql -n 50 --no-pager,重点看是否含
Operation not permitted、Permission denied 或 Failed to create /var/run/mysqld/mysqld.sock
sudo systemctl edit mysql,插入以下内容后重启:
[Service] ProtectHome=false ProtectSystem=false
socket 在 /run/mysqld/(而非 /tmp/),且 pid-file 指向 /run/mysqld/mysqld.pid
即使 chown mysql:mysql /var/lib/mysql 且 chmod 750 正确,SELinux 或 AppArmor 仍可能拦截。MySQL
进程实际以 mysql 用户运行,但受限于内核级强制访问控制。
sestatus;若为
enforcing,尝试临时设为 permissive:sudo setenforce 0,再启动 mysqld。如成功,则需修复上下文:
sudo semanage fcontext -a -t mysqld_db_t "/var/lib/mysql(/.*)?",然后
sudo restorecon -Rv /var/lib/mysql
sudo aa-status | grep mysql,若存在
mysql 配置文件但未加载,或日志中出现 operation="open" + denied,则编辑 /etc/apparmor.d/usr.sbin.mysqld,确保包含 /var/lib/mysql/** rwk,,再执行 sudo apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld
datadir 设在用户家目录(如 /home/user/mysql_data)——ProtectHome=true 会直接禁止访问,且 SELinux/AppArmor 默认不放行MySQL 8.0.22+ 已废弃 mysqld_safe,官方推荐直接由 systemd 管理。如果你仍在用旧版启动脚本或手动执行 mysqld --user=mysql ...,会因缺少 capability(如 CAP_SYS_NICE、CAP_SYS_RESOURCE)而失败。
sudo mysqld --user=mysql —— 这绕过了 systemd 的能力授权,必然失败;必须走 sudo systemctl start mysql
sudo systemctl status mysql查看完整命令行,它实际执行的是
/usr/sbin/mysqld $MYSQLD_OPTS ${MYSQLD_ARGS},其中 $MYSQLD_OPTS 包含必要 capabilities/etc/mysql/mysql.conf.d/ 下的 .cnf 文件,而非仅靠命令行参数;否则 systemd 启动时不会加载新版 systemd 服务单元默认设置 PrivateTmp=true 和 InaccessibleDirectories=/tmp,如果 socket 仍配在 /tmp/mysql.sock,mysqld 将无法创建该文件。
mysqld --verbose --help | grep "socket",确认默认 socket 路径;再查
my.cnf 是否显式设置了 socket = /tmp/mysql.sock
[mysqld] socket = /run/mysqld/mysqld.sock pid-file = /run/mysqld/mysqld.pid,并确保目录存在且属主正确:
sudo mkdir -p /run/mysqld && sudo chown mysql:mysql /run/mysqld
/run 是 tmpfs,重启即清空,所以不能把数据文件放这里;只放 socket/pid 这类运行时文件MySQL 权限类启动失败,绝大多数情况不是“没给 mysql 用户权限”,而是被 systemd 安全策略、SELinux/AppArmor 或路径隔离机制静默拦截。先看 journalctl 日志里的具体 errno 和 operation,再对照对应机制做针对性修复,比盲目 chmod/chown 有效得多。