Errcode: 13错误80%以上由SELinux导致,需先用getenforce或sestatus确认Enforcing模式,再通过setenforce 0临时验证;若MySQL启动成功,则需用semanage fcontext为关键路径(如/var/lib/mysql)添加mysqld_db_t等上下文,并执行restorecon -Rv刷新。

Errcode: 13 错误在 CentOS/RHEL/AlmaLinux/Rocky Linux 上,80% 以上不是权限设错,而是 SELinux 拦住了——别急着 chmod 或 chown,先看上下文。
怎么快速确认是 SELinux 拦的?
运行命令直接判断,不绕弯:
-
getenforce:输出Enforcing就基本坐实了 -
sestatus:确认策略类型(通常是targeted)和当前模式 - 临时验证:
sudo setenforce 0→ 再systemctl start mysqld;如果立刻成功,就是它
注意:setenforce 0 是临时关闭,重启即恢复,仅用于验证,不是解决方案。
为什么 chown mysql:mysql 还是报错?
因为 SELinux 不看用户组和 rwx 权限,它看的是安全上下文(security context)。即使 /var/lib/mysql 属主正确、权限为 750,只要上下文不是 mysqld_db_t,mysqld 进程照样被拒绝写入。
查上下文用:ls -Z /var/lib/mysql。正常应含 mysqld_db_t;若显示 default_t 或 unconfined_u:object_r:var_lib_t:s0,就说明没标对。
典型错误日志:Can't create/write to file './ibdata1' (Errcode: 13),但 ls -ld 显示权限完全正确——这就是上下文错的典型表现。
如何永久修复上下文?
别关 SELinux,精准打标签才是正解。漏掉一个路径(比如 /tmp/ib* 或自定义 pid-file 路径),服务就可能卡在某一步静默失败。
执行以下命令(按需补充):
- 数据目录:
sudo semanage fcontext -a -t mysqld_db_t "/var/lib/mysql(/.*)?"→sudo restorecon -Rv /var/lib/mysql - 配置目录:
sudo semanage fcontext -a -t mysqld_etc_t "/etc/my.cnf.d(/.*)?"→sudo restorecon -Rv /etc/my.cnf.d - 临时文件:
sudo semanage fcontext -a -t mysqld_tmp_t "/tmp/ib.*"→sudo restorecon -v /tmp/ib*
注意:restorecon -Rv 必须加 -v 查看实际变更,避免“以为修了其实没生效”。
Docker 场景下挂载宿主机目录失败怎么办?
在启用了 SELinux 的宿主机上,docker run -v /my/data:/var/lib/mysql 会继承宿主机目录的上下文(如 default_t),容器内 mysqld 仍被拒,日志只报 Permission denied,不提 SELinux。
两种解法:
-
推荐:宿主机先打标:
sudo semanage fcontext -a -t mysqld_db_t "/my/data(/.*)?"→sudo restorecon -Rv /my/data - 运行时自动重标:
docker run -v /my/data:/var/lib/mysql:z(:z表示私有卷,Docker 自动设置mysqld_db_t)
别忽略 /tmp、/run/mysqld、pid-file 路径——audit 日志里 ausearch -m avc -ts recent | grep mysqld 才暴露真实拦截点。


















