« 回到博客列表

解决 macOS 下 MySQL 2002 错误

Feb 7th, 2017阅读本文大约需要 3 分钟

起因

最近在推进公司项目架构的前后端分离,正在做一个 Demo,要用到数据库,结果不知道是不是因为最近一次 macOS 更新的原因,MySQL 启动不了,报如下报错:

mysql -u myUserName -p
[mysql]ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

寻医问药

网上转了一圈,发现解决方案一堆,似乎是个很普遍的问题。但各种说法不同,试了好多都不对症。最后花了半天时间终于找到了解决办法,这里分享下求解过程中学到的一些东西。

先说解决办法

错误提示的意思大概是围绕 /tmp/mysql.sock 这么个文件, cd 过去一看文件不存在,简单查了下,这个文件是在本地通过 socket 方式连接 MySQL 时自动创建的,所以应该不是文件丢失的问题,只是没能正确生成。网上的办法一种是卸载 MySQL 后重装,另一种说创建个同名的软连接指到 /var/lib/mysql/mysql.sock ,前者稍后吐槽,是个巨坑,而且从目前的判断来看也不是很对症,后者看了下至少在我的设备上不存在这个路径,无果而返。

继续查,看到有说用 mysqld_safemysql_install_db 的,看似相关但试了下并不对症。

继续查,又发现一种新的方案,说在 MySQL 的配置文件 /etc/my.cnf 里(没错,就是这个名字,不是 ini,也没有漏掉字母 o)设置一下 [mysqlid] 下面的 socket 的指向,结果神奇的没有这个文件(稍后详解)。一番折腾弄来了这个文件,一看 socket 字段前面果然一个井号注释掉了,改成 socket=/tmp/mysql.sock ,保存退出,重启服务,问题依旧。

整理一下情绪,继续查,这次有人把矛头指向了 PHP,说要配置 /etc/php.ini ,听上去 MySQL 自身的启动应该和 PHP 无关才对,但谁能想到还真就是这里的原因。 php.ini 中有三个字段与socket有关:pdo_mysql.default_socketmysqli.default_socketmysql.default_socket。在我的设备上只有第一个值为 /tmp/mysql.sock ,后两个都为空,全都填上之后,重启服务,绿灯!再看 /etc ,顺利生成了 mysql.sock 文件。

MySQL 请神容易送神难

MySQL 提供了二进制的安装包,安装非常简单,初始化的配置也不是很难,但是官方并没有提供卸载的途径,要卸载只能手动去清理一个个的目录,具体哪些目录这里就不列了,百度很容易就能查到。

macOS 不自带 /etc/my.cnf

求解过程中涉及到 MySQL 的配置文件 /etc/my.cnf ,这个文件默认安装过程是没有的,如果需要对 MySQL 进行配置需要手动从 /usr/local/mysqli/support-files/my-default.cnf 拷贝过来之后再编辑。这个文件中也以注释的形式写到 /etc/my.cnf 是 MySQl 访问配置文件时最先查找的位置,对它的配置可以覆盖默认配置。

便捷的控制 MySQL 服务

MySQL 在安装好之后会在系统的偏好设置里有一个专门的面板,可以用来启动/停止 MySQL 服务,但作为开发者或许会更加倾向于通过命令行直接操作。(或许有更好的方法我不知道,但至少这个方法不算太糟,如果有更好方法请一定告诉我)

MySQL 服务的启动命令是 /usr/local/mysql/support-files/mysql.server ,后面跟参数start/stop/restart,每次都要输这么一长串太麻烦,直接写到 shell 的配置文件里作为 alias 就好了。我用的是 zsh,那就到 ~/.zshrc 里添加:

alias mysqlstart="/usr/local/mysql/support-files/mysql.server start"
alias mysqlstop="/usr/local/mysql/support-files/mysql.server stop"
alias mysqlrestart="/usr/local/mysql/support-files/mysql.server restart"

小结

配置真是一个磨人的小妖精,尤其当涉及文件众多、单个文件参数又特别繁杂的时候,在对这些参数不熟悉的前提下免不了会花大量时间在那里折腾。运维这事儿说大不大但真遇到问题了就发现其实也不容易,DevOps 难做啊。