一、背景
最近在使用 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=mysql
default-storage-engine=INNODB
character-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 NAMES
e6946816696d a1-api:latest "java -Djava.securit…" 24 hours ago Up 24 hours 0.0.0.0:8080->8080/tcp a1
edc4e7ef57df mysql:5.7 "docker-entrypoint.s…" 24 hours ago Up 24 hours 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
bogon:config eric$ docker exec -it edc4e7ef57df /bin/bash
bash-4.2# cd /var/lib/mysql
bash-4.2# ls -l
total 181288
-rw-r----- 1 root root 56 Jan 29 11:09 auto.cnf
drwxr-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 ibdata1
drwxr-x--- 77 root root 2464 Jan 29 11:09 mysql
lrwxrwxrwx 1 root root 27 Jan 29 11:09 mysql.sock -> /var/run/mysqld/mysqld.sock
drwxr-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.pem
drwxr-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 -l
total 387152
-rw-r----- 1 eric staff 56 1 29 11:09 auto.cnf
drwxr-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 ibtmp1
drwxr-x--- 77 eric staff 2464 1 29 11:09 mysql
lrwxrwxrwx 1 eric staff 27 1 29 11:09 mysql.sock -> /var/run/mysqld/mysqld.sock
drwxr-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.pem
drwxr-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 重启的时候报错!
三、解决办法
这里提供一个简单粗暴的方案来解决这个问题,就是直接去掉软链接。文章来源:https://www.toymoban.com/news/detail-558500.html
方法是我们通过修改 my.cnf 文件来重新指定 mysql.sock 文件的生成路径,如下:文章来源地址https://www.toymoban.com/news/detail-558500.html
[mysqld]
user=mysql
default-storage-engine=INNODB
character-set-server=utf8
pid-file=/var/lib/mysql/mysql.pid
# 将 socket 的默认地址(/var/run/mysqld/mysqld.sock)改为 /var/lib/mysql/mysql.sock
socket=/var/lib/mysql/mysql.sock
datadir=/var/lib/mysql
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
到了这里,关于docker-compose重新启动Mysql报错changing ownership of ‘/var/lib/mysql/mysql.sock‘: No such file or direct的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!