mysql.sock 的三种配置路径

背景

五一期间,我用前端三件套写一个自用的浏览器插件,后端程序用 nodejs,它会连接 MySQL8.0.33 数据库,3306 端口。这个数据库是跑在我的 vmware 虚拟机里的,它同时是我的实验环境,上面还利用多实例部署方式,跑了另外一个 MySQL5.7.39 的实例,运行在 3307 端口。

近期我家中经历了一次断电事件,导致我正在运行的 VMware 虚拟机随着主机一同断电。尽管我的电脑在 BIOS 中设置了电源恢复后自动启动,并且 VMware 也配置了在主机启动时自动开启相应的虚拟机环境,但是在虚拟机重启后,我发现 mysqld 服务并未如预期般自动启动。这与我在之前的文章《多实例下,mysql 服务自启动有概率失败的原因》中所描述的问题相符。这很糟糕,为了解决这件事,有了这篇文章。

导读,希望详细了解本文编写的背景故事,可以按顺序阅读我之前写的两篇文章《MySQL5.7 为什么多了个 sock.lock 文件》《多实例下,mysql 服务自启动有概率失败的原因》

为了节省读者的流量费,我简单地概括一下这两篇文章的内容。

《MySQL5.7 为什么多了个 sock.lock 文件》一文解析了 MySQL5.7 版本为何新增了 mysql.sock.lock 文件。这一改变是为修复一个 Bug:当用户未正确配置 socket 参数,可能导致访问错误的数据库实例,或在尝试关闭数据库时误关其他实例。为此,mysql.sock.lock 文件应运而生。

在《多实例下,mysql 服务自启动有概率失败的原因》一文中,我讨论了 MySQL5.7 引入 mysql.sock.lock 所导致的新问题。这一改动可能导致在多实例混合部署的环境中,MySQL5.7 及以上版本在服务器意外断电重启后,部分 mysqld 实例有可能无法成功启动。针对此问题,我提出了一种解决方案:将 mysql.sock 路径设定在易失性设备 tmpfs 上,这样可以有效避免启动失败的情况。

在 CentOS7 默认安装下,/tmp 并没有独立分区,而是在 / 目录下的。

我最近在测试 openEuler22.03 LTS,我惊讶地发现,这个系统默认安装下,/tmp 是独立分区的,并且就是挂载在易失性设备 tmpfs上的。

(如图,两个系统的默认安装下对比)

这么说,其实 mysql.sock 可以放在 /tmp 目录下,以便利用 tmpfs 特性解决我现在的痛点。

mysql.sock 有三种配置路径

有了上述背景故事,我认为 mysql.sock 一般会有三种配置路径玩法。

  • 第一种,@@datadir,也就是数据目录
  • 第二种,/tmp,系统的临时目录
  • 第三种,专门建了个放 sock 的目录

我佛性询问了 10 位管理 200 个到 几千个 MySQL 实例的老师,他们配置的 mysql.sock 路径如下


调研对象 选择
芬老师(我) @@datadir
林老师 @@datadir
陈老师 @@datadir
李老师 @@datadir
杨老师 @@datadir
洪老师 专门建了个放 sock 的目录
威老师 专门建了个放 sock 的目录
杨老师 2 专门建了个放 sock 的目录
王老师 专门建了个放 sock 的目录
田老师 @@tmpdir

@@datadir 表示参数 datadir 定义的路径,即放在数据目录下

@@tmpdir 表示参数 tmpdir 定义的路径,即存放 MySQL 临时文件的目录

专门建了个放 sock 的目录,规范一些的话,一般建的目录名叫做 run,例如 /database/mysql/run/

我们知道定义 MySQL 的 sock 路径是通过 socket 参数控制的。而官方默认值如下

意思是,如果采用源码和二进制方式部署,默认值是 socket=/tmp/mysql.sock,采用 RPM 部署的话,默认值是 socket=/var/lib/mysql/mysql.sock

socket=/var/lib/mysql/mysql.sock 可以认为是属于第三种"专门建了个放 sock 的目录"的设置。

在生产环境中,大部分人倾向于使用二进制部署方式。我们现在发现一个有趣的现象,大佬们居然不按官方默认值规范来部署设置 socket=/tmp/mysql.sock,这是为什么?

第一种,mysql.sock 放在/tmp 系统的临时目录

实际上,在以前我学习 MySQL5.6 的时候,老师示范时都是把 mysql.sock 放置在 /tmp 目录下的,再结合二进制部署情况下,默认值也是在 /tmp 下,导致大家都认为这是最佳实践,其实不然。他们这样做的主要原因,其实是为了方便,因为保持和官方默认值一致,那么使用 socket 方式登录数据库时可以省略输入 socket 路径。

mysql -u用户 -p密码 -hlocalhost -S /tmp/mysql.sock # 默认设置下,和下面这个是等价的 mysql -u用户 -p密码