修改Docker数据目录后启动MySQL镜像提示数据目录不可用如何解决
问题根因
errno: 13是Linux系统标准的权限拒绝错误,该问题触发于修改Docker数据目录(data-root)之后,本质是新Docker数据路径的权限、挂载配置不符合容器运行要求,最终导致两个核心异常:
- MySQL容器内部
/tmp路径无写入权限,无法创建InnoDB初始化所需的临时文件 - 挂载到容器内
/var/lib/mysql的宿主机数据目录权限不匹配,MySQL进程无读写权限
排查步骤
- 检查新Docker数据目录所在文件系统的挂载参数:执行
mount | grep 你的新Docker数据目录绝对路径,重点排查是否存在ro(只读挂载)、no_tmpfile、root_squash(NFS等网络存储常见配置)这类会阻止文件创建的参数,正常本地分区使用defaults参数即可。 - 检查新Docker数据根目录本身的权限:执行
ls -ld 你的新Docker数据目录绝对路径,要求属主为root:root,目录权限不低于700,如果迁移目录时用普通复制命令没带归档参数,很容易丢失原有权限配置。 - 检查MySQL容器挂载的宿主机数据目录权限:执行
ls -ld 你映射给容器/var/lib/mysql的宿主机目录绝对路径,官方MySQL镜像内运行进程的UID/GID固定为999,目录属主不匹配会直接导致写入失败。 - 检查
/etc/docker/daemon.json配置:确认是否开启了"no-new-privileges": true,该配置会阻止容器内进程获取必要的权限绕过规则,容易触发文件访问拒绝。 - 快速定位问题范围:启动一个临时测试容器,复用和MySQL完全一致的目录挂载配置,进入容器后直接尝试在对应路径创建文件,快速区分是Docker全局配置问题还是单目录权限问题,测试命令如下:
# 替换命令中挂载路径为你实际给MySQL配置的宿主机数据路径 docker run --rm -it -v /你的宿主机MySQL数据路径:/var/lib/mysql alpine sh # 进入容器后依次执行两条创建命令,看哪条报Permission denied touch /tmp/test touch /var/lib/mysql/test
解决方法
- 修复挂载参数问题:如果是本地磁盘分区挂载异常,编辑
/etc/fstab将对应分区的挂载参数改为defaults,执行mount -o remount 对应分区挂载点即时生效;如果是NFS等网络存储,需要在存储服务端关闭root_squash配置,添加no_root_squash参数后重新挂载。 - 修复Docker根目录权限:如果是迁移目录导致的权限丢失,执行以下命令修复后重启Docker服务:
chown -R root:root /你的新Docker数据目录绝对路径 chmod 700 /你的新Docker数据目录绝对路径 systemctl restart docker
- 修复MySQL数据目录权限:直接将宿主机上的MySQL挂载目录属主改为999:999,和容器内MySQL运行用户匹配即可,不需要设置777等宽松权限:
chown -R 999:999 /你的宿主机MySQL数据路径
- 修复daemon.json配置问题:如果开启了
no-new-privileges配置,要么暂时将该配置设为false后重启Docker验证,要么在启动MySQL容器时添加--cap-add=DAC_OVERRIDE参数,允许容器内进程绕过文件权限检查。 - 残留文件清理:修复权限后第一次启动如果还报错,先清空宿主机MySQL数据目录下之前初始化失败生成的残留文件(比如ibdata1、auto.cnf等),再重新启动容器即可。
内容的提问来源于stack exchange,提问作者mohammad amin rahimi
相关产品推荐
相关产品推荐

