mysql 无法启动的终极解决方案

按官网教程,一步步安装mysql 5.7.40。但是,总是无法正常启动。查看日志,发现错误信息:

[ERROR] Can't start server : can't check PID filepath: No such file or directory

问谷哥、度娘,大部分文章都说原因是 /var/run下无相应目录,解决方法是输入如下指令:

mkdir /var/run/mysqld
chown  mysql:mysql /var/run/mysqld

创建好目录,并改变目录属主后,mysql确实可以正常启动了。但是悲剧的是,只要主机一重启,又出现上述错误了。一查看,/var/run下的mysqld目录又不见了。

看来,网上大部分文章都没有彻底解决问题。深入学习后,发现/var/run这个目录不是正常的文件系统。根据linux的文件系统分层结构标准(FHS)中的定义,/var/run 目录中存放的是自系统启动以来描述系统信息的文件,这个文件夹中的所有文件将在系统启动时清空。

看来,这是mysql的一个bug了,别的软件都能在清空后重建,但是mysql却没有重建。

首先想利用systemctl service配置文件中的ExecStartPre 选项,在mysql服务启动前创建目录。但是,发现缺省状态下,mysql服务使用的用户mysql没有在这个地方创建目录的权限。要想创建目录,必须把mysql服务的启动用户改为root,这降低了安全性,不是好的解决方案。

其次,想到利用 crontab 指令的@reboot选项在系统重启时创建目录。实践证明,这个方法是成功的,配置方法参见《定制Linux系统中设置开机自启动程序》

虽然通过crontab解决了这个问题,但是总觉得不是最佳方案。为啥别的软件,如PHP,都能在系统启动时在这个文件夹新建文件?肯定是有什么正常方法,绕过了权限限制。进一步深入学习,终于发现了终极解决方案。

原来,Linux系统在重启时,会扫描/usr/lib/tmpfiles.d/ 目录,按照这个目录下的conf文件需求,由系统在/var/run下创建相应目录、文件或者链接。下面是php8.1在这个目录下文件php8.1-fpm.conf的内容:

#Type  Path                   Mode    UID                     GID                   Age   Argument
    d        /run/php          0755      www-data      www-data       -       -

上述文件,指示系统启动后在/var/run目录下,创建一个名为php的目录,属性为0755,用户和组均为www-data。等一下!有人眼尖看出来,不是/var/run,是/run呀?

情况是这样的:早期Linux标准是/var/run,后来的版本都改成/run了。为了兼容,将/var/run变成了链接,指向/run目录。因此,这个两个目录是一回事,基本可以互换。

conf文件中,第1列是类型,有32种选项,详见Ubuntu的官方文档,常用的有d-目录,f-文件,L-链接。第2列是路径,第3列是属性,第4列是用户,第5列是用户组,第6列是寿命,单位可以是分、秒、小时、天、周,只要当前时间超过创建时间加寿命,这个目录或文件就会被删除。缺省不设置,就是永远不删除,直至系统重启。第7列是参数,根据第1列的类型,参数有不同含义,如类型是文件(f)时,参数表示要写入文件的内容。

学习了这些基本知识后,回过头来,要解决本文开头mysql无法启动的问题就很简单了,只要在/usr/lib/tmpfiles.d/目录下,写入一个相应的文件mysql.conf即可,指令如下:

echo "d /var/run/mysqld 0755 mysql mysql" > /usr/lib/tmpfiles.d/mysql.conf

这就是正确的终极解决方案!

发表评论