Can't connect to local MySQL server through socket '/tmp/mysql.sock'

MySQL

Written by Kohei Yamada Posted on 2016/11/14



はじめに

PHPからMySQLサーバーへアクセスしようとした際、以下のようなエラーが発生しました。

SQLSTATE[HY000] [2002] Can't connect to local MySQL server through socket '/tmp/mysql.sock'

「ソケット'/tmp/mysql.sock'を通してローカルのMySQLサーバへアクセスができません。」といった内容です。

MySQLは起動時にmysql.sockというソケットファイルを作成します。そしてPHPや他のプログラムはこのソケットファイルを通してMySQLへアクセスを行うことができます。
どうやらここが怪しそうです。

調査

といことで、このPHPエラーが/tmp/mysql.sockへアクセスしようとしていたということなので、まずは/tmp/mysql.sockがあることを確認してみます。

$ ls /tmp/mysql.sock
ls: /tmp/mysql.sock にアクセスできません: そのようなファイルやディレクトリはありません

おぉ、そもそもアクセスしようとしている場所にmysql.sockがないみたいです。。。
ではどこにあるのでしょうか???
my.cnfを見てみます。

$ grep mysql.sock /etc/my.cnf
socket          = /var/lib/mysql/mysql.sock
socket          = /var/lib/mysql/mysql.sock

ここで設定されているのは/va/lib/mysql/mysql.sockです。
ちなみに2つ存在するのは[client][mysqld]で設定されているからです。
では、確かめてみます。

$ ls /var/lib/mysql/mysql.sock
/var/lib/mysql/mysql.sock

ありました。

原因

これでわかったのが、
「MySQLはソケットを/var/lib/mysql/mysql.sockに用意して待ち構えているけれど、PHPは/tmp/mysql.sockにソケットがあると思ってアクセスしにいっているためエラーが発生している。」
ということです。

対策

なので今回はmy.cnfを修正してソケットを/tmp/mysql.sockへ作成するように変更します。
まずはmysqlを停止しておきましょう。

$ sudo service mysqld stop
Shutting down MySQL. SUCCESS!

それでは修正します。

$ vi /etc/my.cnf
$ grep mysql.sock /etc/my.cnf
socket          = /tmp/mysql.sock
socket          = /tmp/mysql/mysql.sock

起動します。

$ sudo service mysqld start
Starting MySQL. SUCCESS! 

それではソケットが作成されたか確認しましょう。

$ ls /tmp/mysql.sock
/tmp/mysql.sock

無事、指定した場所に作成されました。

$ tail -f /var/log/mysql/mysql.log
             30 Connect     hogehoge@localhost on hogehoge
             30 Quit       
             32 Connect     hogehoge@localhost on hogehoge
             31 Connect     hogehoge@localhost on hogehoge
             32 Quit       
             31 Quit

アクセスログも正常に出力されているみたいです。

以上で、エラーは解消されました。

おわりに

今回は受け手となるMySQL側のソケットデフォルト位置と送り手となるPHP側MySQLのデフォルトソケット位置が異なるために発生したエラーでした。
念のため対応後、PHP側の設定(php.ini)を確認したところ、MySQLソケットを指定する箇所に指定がありませんでした。

$ grep socket /etc/php.ini
; Default timeout for socket based streams (seconds)
default_socket_timeout = 60
; Default socket name for local MySQL connects.  If empty, uses the built-in
mysql.default_socket =
; Default socket name for local MySQL connects.  If empty, uses the built-in
mysqli.default_socket =

なのでこちらでMySQLのソケット位置を設定してあげても良かったかもです。

ということで、とりあえず今回は、MySQL側の設定(my.cnf)を指定することで対応しましたが、PHP側の設定(php.ini)で対応しても解決できたと思われます。