docker-compose重新启动Mysql报错changing ownership of ‘/var/lib/mysql/mysql.sock‘: No such file or direct
一、背景
最近在使用 docker-compose 编排整合一个项目(springboot+mysql)的时候,首次启动后重新再启动的时候,mysql 容器启动失败,通过 docker logs 命令查看 mysql 容器的启动日志如下:
chown: changing ownership of '/var/lib/mysql/mysql.sock': No such file or directory
docker-compose.yml 文件完整内容如下:
version: '3'services: mysql: image: mysql:5.7 restart: always container_name: mysql #使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限 #设置为true,不然数据卷可能挂载不了,启动不起 privileged: true environment: MYSQL_ROOT_PASSWORD: mysql123321 TZ: Asia/Shanghai ports: - 3306:3306 volumes: - /Users/cab5/docker_compose/bas/mysql/data:/var/lib/mysql - /Users/cab5/docker_compose/bas/mysql/config/my.cnf:/etc/mysql/my.cnf - /Users/cab5/docker_compose/bas/mysql/init:/docker-entrypoint-initdb.d/ - /Users/cab5/docker_compose/bas/mysql/sql:/opt/sql command: --max_connections=1000 --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --default-authentication-plugin=mysql_native_password a1-api: image: a1-api:latest restart: always container_name: a1 ports: - 8080:8080 depends_on: - mysql links: - mysql
my.cnf 文件完整内容如下:
[mysqld]user=mysqldefault-storage-engine=INNODBcharacter-set-server=utf8[client]default-character-set=utf8[mysql]default-character-set=utf8
二、问题分析
从报错信息上来看,应该是 mysql 启动的时候要去 /var/lib/mysql 路径找 mysql.sock 文件,但是该路径下没有这个文件,所以导致报错。
这里有一个问题是:为什么首次启动的时候没有报错,重启才出现的这个问题呢?
首先,mysql 首次启动的时候,默认情况下会在容器内的 /var/lib/mysql 路径下生成一些文件,如下:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMESe6946816696d a1-api:latest "java -Djava.securit…" 24 hours ago Up 24 hours 0.0.0.0:8080->8080/tcp a1edc4e7ef57df mysql:5.7 "docker-entrypoint.s…" 24 hours ago Up 24 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysqlbogon:config eric$ docker exec -it edc4e7ef57df /bin/bashbash-4.2# cd /var/lib/mysqlbash-4.2# ls -ltotal 181288-rw-r----- 1 root root 56 Jan 29 11:09 auto.cnfdrwxr-x--- 5 root root 160 Jan 29 11:09 bas_database-rw------- 1 root root 1676 Jan 29 11:09 ca-key.pem-rw-r--r-- 1 root root 1112 Jan 29 11:09 ca.pem-rw-r--r-- 1 root root 1112 Jan 29 11:09 client-cert.pem-rw------- 1 root root 1680 Jan 29 11:09 client-key.pem-rw-r----- 1 root root 1301 Jan 29 11:09 ib_buffer_pool-rw-r----- 1 root root 50331648 Jan 29 11:10 ib_logfile0-rw-r----- 1 root root 50331648 Jan 29 11:09 ib_logfile1-rw-r----- 1 root root 79691776 Jan 29 11:10 ibdata1drwxr-x--- 77 root root 2464 Jan 29 11:09 mysqllrwxrwxrwx 1 root root 27 Jan 29 11:09 mysql.sock -> /var/run/mysqld/mysqld.sockdrwxr-x--- 91 root root 2912 Jan 29 11:09 performance_schema-rw------- 1 root root 1680 Jan 29 11:09 private_key.pem-rw-r--r-- 1 root root 452 Jan 29 11:09 public_key.pem-rw-r--r-- 1 root root 1112 Jan 29 11:09 server-cert.pem-rw------- 1 root root 1676 Jan 29 11:09 server-key.pemdrwxr-x--- 108 root root 3456 Jan 29 11:09 sys
从上边的文件列表中,我们可以看到 mysql.sock 这个文件(重启的时候就是因为找不到这个问题件才会报错的),目前来看容器内是有这个文件。
又从 docker-compose.yml 文件中,我们可以看到该目录(/var/lib/mysql)被挂载到了本地的 /Users/cab5/docker_compose/bas/mysql/data 目录下,让我们来看本地目录下的文件,如下:
bogon:data cab5$ ls -ltotal 387152-rw-r----- 1 eric staff 56 1 29 11:09 auto.cnfdrwxr-x--- 5 eric staff 160 1 29 11:09 bas_database-rw------- 1 eric staff 1676 1 29 11:09 ca-key.pem-rw-r--r-- 1 eric staff 1112 1 29 11:09 ca.pem-rw-r--r-- 1 eric staff 1112 1 29 11:09 client-cert.pem-rw------- 1 eric staff 1680 1 29 11:09 client-key.pem-rw-r----- 1 eric staff 1301 1 29 11:09 ib_buffer_pool-rw-r----- 1 eric staff 50331648 1 29 11:10 ib_logfile0-rw-r----- 1 eric staff 50331648 1 29 11:09 ib_logfile1-rw-r----- 1 eric staff 79691776 1 29 11:10 ibdata1-rw-r----- 1 eric staff 12582912 1 29 11:10 ibtmp1drwxr-x--- 77 eric staff 2464 1 29 11:09 mysqllrwxrwxrwx 1 eric staff 27 1 29 11:09 mysql.sock -> /var/run/mysqld/mysqld.sockdrwxr-x--- 91 eric staff 2912 1 29 11:09 performance_schema-rw------- 1 eric staff 1680 1 29 11:09 private_key.pem-rw-r--r-- 1 eric staff 452 1 29 11:09 public_key.pem-rw-r--r-- 1 eric staff 1112 1 29 11:09 server-cert.pem-rw------- 1 eric staff 1676 1 29 11:09 server-key.pemdrwxr-x--- 108 eric staff 3456 1 29 11:09 sys
在本地的 /Users/cab5/docker_compose/bas/mysql/data 目录下,我们也找到了 mysql.sock 文件。
按着这个道理来说,mysql重启的时候从挂载的目录( /Users/cab5/docker_compose/bas/mysql/data)下应该能找到 mysql.sock 文件啊?为什么会报 No such file or directory 这个错呢?
让我们回头再仔细看下容器内的 mysql.sock 文件。原来,Ta 后边还有一个软链接 /var/run/mysqld/mysqld.sock!
mysql 容器首次启动的时候,在生成 /var/lib/mysql/mysql.sock 文件的同时还会生成一个对应的软连接 /var/run/mysqld/mysqld.sock。
我们再看下与容器内 /var/lib/mysql 目录挂载的本地目录(/Users/cab5/docker_compose/bas/mysql/data)中的 mysql.sock 文件,后边也有一个软链接(也就是说挂载会把软链接一并带到本地)。
但是,软链接的文件(/var/run/mysqld/mysqld.sock)在本地真的存在吗?
让我们通过 cd 命令来看看 /var/run/mysqld/mysqld.sock 文件是否存在于本地,如下:
bogon:data cab5$ cd /var/run/mysqld/-bash: cd: /var/run/mysqld/: No such file or directory
这里得出一个结论:挂载虽然把容器内的软链接带到了本地,却并没有在本地生成真的文件。
同时造成问题出现的原因也就明了了:
mysql 容器重启的时候会在容器内的 /var/lib/mysql 目录下找 mysql.sock 文件,由于该目录实际是挂载到了本地的 /Users/cab5/docker_compose/bas/mysql/data 目录下。所以,实际上就是去 /Users/cab5/docker_compose/bas/mysql/data 目录下找 mysql.sock 文件 ,又由于该目录下的 mysql.sock 文件实际是个软链接( /var/run/mysqld/mysqld.sock),且该软链接指向的文件在本地根本不存在,所以导致 mysql 重启的时候报错!
三、解决办法
这里提供一个简单粗暴的方案来解决这个问题,就是直接去掉软链接。
方法是我们通过修改 my.cnf 文件来重新指定 mysql.sock 文件的生成路径,如下:
[mysqld]user=mysqldefault-storage-engine=INNODBcharacter-set-server=utf8pid-file=/var/lib/mysql/mysql.pid# 将 socket 的默认地址(/var/run/mysqld/mysqld.sock)改为 /var/lib/mysql/mysql.socksocket=/var/lib/mysql/mysql.sockdatadir=/var/lib/mysql[client]default-character-set=utf8[mysql]default-character-set=utf8
来源地址:https://blog.csdn.net/yangchao1125/article/details/128785894
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341