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=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 重启的时候报错!

三、解决办法

这里提供一个简单粗暴的方案来解决这个问题,就是直接去掉软链接

方法是我们通过修改 my.cnf 文件来重新指定 mysql.sock 文件的生成路径,如下:

[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
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cab5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值