Errcode: 13或Permission denied八成是SELinux上下文不匹配;先运行getenforce和sestatus确认是否Enforcing模式,再用setenforce 0临时验证,若启动成功即证实问题;接着用ls -Z检查/var/lib/mysql上下文是否为mysqld_db_t,否则执行semanage fcontext -a -t mysqld_db_t "/var/lib/mysql(/.*)?"并restorecon -Rv修复。

MySQL启动失败报Errcode: 13或Permission denied,80%以上是SELinux上下文不匹配,不是chmod或chown没设对。
怎么快速确认是不是SELinux拦的
别急着改权限或重装——先看SELinux状态:
- 运行
getenforce:输出Enforcing就基本坐实了 - 运行
sestatus:确认Current mode是enforcing,且Loaded policy name是targeted - 临时验证:执行
sudo setenforce 0,再试systemctl start mysqld;如果立刻成功,就是SELinux上下文问题
注意:setenforce 0 只是临时切换到宽容模式,重启后失效,仅用于验证。
为什么chown mysql:mysql还是报错
因为SELinux不看传统用户组权限,它检查的是文件/目录的security context。即使 /var/lib/mysql 属主正确,若上下文不是 mysqld_db_t,mysqld 进程仍被拒绝写入。
- 查当前上下文:
ls -Z /var/lib/mysql,正常应含mysqld_db_t - 典型错误日志:
Can't create/write to file './ibdata1' (Errcode: 13),但ls -ld显示权限完全正确 - audit日志里会出现
avc: denied { write } ... tcontext=...:var_lib_t,说明目标类型是var_lib_t而非mysqld_db_t
修复数据目录和关键路径的SELinux上下文
必须用 semanage fcontext 注册规则,再用 restorecon 生效——不能只靠 chcon 临时修改,否则升级或重装后丢失。
- 标准数据目录:
sudo semanage fcontext -a -t mysqld_db_t "/var/lib/mysql(/.*)?",然后sudo restorecon -Rv /var/lib/mysql - 自定义数据目录(如
/data/mysql):sudo semanage fcontext -a -t mysqld_db_t "/data/mysql(/.*)?",再restorecon -Rv /data/mysql - socket文件路径(如
/var/lib/mysql/mysql.sock):sudo semanage fcontext -a -t mysqld_var_run_t "/var/lib/mysql/mysql\.sock"(注意点号要转义),再sudo restorecon -v /var/lib/mysql/mysql.sock - 非标端口(如
port = 3307)需授权:sudo semanage port -a -t mysqld_port_t -p tcp 3307
Docker挂载宿主机目录时的SELinux问题
在启用SELinux的宿主机上,用 -v /my/data:/var/lib/mysql 启动容器,即使宿主机目录权限全开,也会因上下文继承失败被拒——容器内看到的仍是 unconfined_u:object_r:default_t:s0,不是 mysqld_db_t。
- 推荐方案:宿主机先打标签:
sudo semanage fcontext -a -t mysqld_db_t "/my/data(/.*)?"→sudo restorecon -Rv /my/data - 运行时方案:加
:z标签启动:docker run -v /my/data:/var/lib/mysql:z,Docker会自动重标上下文 - 漏掉临时路径(如
/tmp/ib*或自定义pid-file)也可能静默失败,查ausearch -m avc -ts recent | grep mysqld才能暴露真实拦截点
SELinux的难点不在“关不关”,而在“标不标对”——少一个路径、漏一个转义、缺一个端口授权,都可能让MySQL卡在某一步无声退出。


















