OS errno 13报错常由SELinux强制模式拦截引起,即使文件属主和权限正确;可通过getenforce、ausearch或journalctl确认AVC拒绝日志;修复应使用semanage声明上下文类型(如mysqld_db_t)并执行restorecon -Rv生效,而非直接关闭SELinux。

为什么 mysqld 启动报 OS errno 13(Permission denied)却不是文件权限问题
看到 File './binlog.index' not found (OS errno 13 - Permission denied) 或类似日志,别急着 chown 或 chmod。SELinux 在 Enforcing 模式下会拦截合法的文件访问——即使 ls -l 显示属主正确、读写可执行,进程仍被拒绝,因为上下文类型(context)不匹配。
怎么确认是 SELinux 导致的启动失败
运行以下命令快速验证:
-
getenforce—— 若输出Enforcing,嫌疑极大 -
ausearch -m avc -ts recent | grep mysqld—— 查看最近 AVC 拒绝记录,有输出即实锤 -
journalctl -u mysqld -n 50 --no-pager | grep -i "avc\|selinux"—— systemd 日志里常带关键词
如果没装 audit 工具,先装:yum install audit(CentOS/RHEL)或 apt install auditd(Debian/Ubuntu)。
不关 SELinux,怎样给 MySQL 数据目录加对的安全上下文
直接关闭 SELinux 是调试捷径,但生产环境必须配策略。关键就两步:
- 用
semanage fcontext -a -t mysqld_db_t "/path/to/your/mysql/data(/.*)?"声明路径类型(注意末尾(/.*)?表示递归) - 立即生效:
restorecon -Rv /path/to/your/mysql/data - 若提示
command not found,先装工具:yum install policycoreutils-python-utils(RHEL 8+)或policycoreutils-python(RHEL 7) - 验证是否生效:
ls -Z /path/to/your/mysql/data—— 第二列应含mysqld_db_t
常见错误:只改了目录本身,没加 (/.*)?,导致子目录仍是 default_t;或漏掉 restorecon,声明只是“规则”,不执行不会改实际上下文。
插件加载失败(errno 13 + “cannot restore segment prot”)怎么办
这类报错多见于自定义安装路径(如 /usr/local/mysql)或启用 InnoDB 引擎时,本质是共享库路径未被标记为可执行内存映射。
- 给插件目录打标签:
semanage fcontext -a -t mysqld_plugin_t "/usr/local/mysql/lib/mysql/plugin(/.*)?" - 重置上下文:
restorecon -Rv /usr/local/mysql/lib/mysql/plugin - 若仍失败,检查是否启用了
setroubleshoot,它能自动建议修复命令:sudo setsebool -P mysqld_disable_trans 1(慎用,仅临时绕过)
最易忽略的是:SELinux 策略是分层的,mysqld_db_t 解决数据读写,mysqld_plugin_t 解决动态库加载,mysqld_etc_t 解决配置文件读取——缺一不可。











