2008/08/27

Mysqlのソケット

「Can't connect to local MySQL server through socket」エラーについて

■ このような場合に参考にして下さい
MySQLのクライアントソフト(mysql,PHP,Perl他)からMySQLサーバーに接続しようとすると
「Can't connect to local MySQL server through socket '/tmp/mysql.sock'」
のようなエラーが出て接続に失敗する。


■ 対処方法の前に
まずはじめに、エラーメッセージは次の意味を持ちます。

「ソケット'/tmp/mysql.sock'を通じてローカルのMySQLサーバーに接続することが出来ません」ソケットとはプロセスやネットワーク間の通信機構のことで、MySQLではこのソケットを通じてサーバーとクライアントとが接続されます。ソケットというとポート番号を指定して利用する方法が思い浮かびますが、ここでは/tmp/mysql.sockというファイルが出てきています。

これはUNIXドメインソケット(ファイルシステムソケット)と言って、UNIX系OS特有のソケットで、ローカルシステム内での通信を行う場合に用いられます。このソケットの実態はファイルでサーバー・クライアント間の通信は、実際は、このファイルの入出力を通じて行われます。


■ 対処方法
このエラーが発生する原因には以下の3つが考えられます。

▽ MySQLサーバーが起動していない

MySQLサーバーが生存していないとこのエラーが出ます。
ps ax | grep mysqld
などのコマンドで確認して下さい。


▽ MySQLサーバーで使っているUNIXソケットとクライアントソフトで使っているUNIXソケットのパスが違う

当然、サーバーとクライアントは同じソケットファイルを参照しなければならないのですが、
関連する各ソフトのインストール方法が異なる場合は、違うソケットが参照される場合があります。
(例えば、MySQLはソースからインストール、PHPはRPMでインストールというように)
この場合、MySQLサーバーは/tmp/mysql.sockを利用しているのにPHPでは/var/lib/mysql/mysql.sockに接続しに行こうとする、というような事態になり接続が成立しません。

解決方法としては、MySQLサーバーに合ったソフトをインストールするのが一番良いのですが、
次のような方法も考えられます。

(1) MySQLサーバーで使うソケットをクライアントに合わせる

これは/etc/my.cnfの[mysqld]→socket項目を編集して行います。


[mysqld]

# socket=/var/lib/mysql/mysql.sock

socket=/tmp/mysql.sock

この場合、MySQL標準クライアントプログラムのソケットも変えておいた方が良いでしょう。

同じく/etc/my.cnfの[client]→socket項目を編集します。

[client]
socket=/tmp/mysql.sock


(2) クライアント側で接続先のソケットを指定する

例えばPHPの場合、

if(!$con=mysql_connect("localhost","mysql","passwd")){

if(!$con=mysql_connect("localhost:/var/lib/mysql/mysql.sock","mysql","passwd")){

      Perlの場合、

$dbh=DBI->connect("DBI:mysql:tsumiki:localhost","mysql","passwd",
  {RaiseError=>0,PrintError=>1,AutoCommit=>1});

$dbh=DBI->connect("DBI:mysql:tsumiki;host=localhost;port=/var/lib/mysql/mysql.sock",
  "mysql","passwd",{RaiseError=>0,PrintError=>1,AutoCommit=>1});

のようにポート番号を指定する個所でソケットファイルへのパスを指定することが出来ます。

▽ なんらかの理由でソケットファイルが削除されている

最後に、ソケットファイルが削除されている場合があります。

この場合、MySQLサーバーを一旦シャットダウンして再起動をかけるとソケットファイルが復元されます。
※ MySQL標準のクライアントプログラムはオプション--hostでIPアドレスを指定すると、非ソケットファイル経由での接続が行われます。

例えば次のようなコマンドでMySQLサーバーをシャットダウンして下さい。

mysqladmin --host=192.168.10.100 shutdown

もし、これでもソケットファイルが作成されない場合は
ソケットファイル格納ディレクトリのパーミションの問題が考えられます。
ソケットを作成できない場合はMySQLのエラーログが出力されるのでそれを参考にして下さい。

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

の場合再発防止のためにソケットファイルを保護しておく

まず/temp以下を保護する。
ルートユーザもしくはスーパーユーザでログインして
chmod +t /tmp
念のため権限をチェックします。
ls -ld /tmp

ソケットのパスは/etc/my.cnfに記述

ソケットが通信ができているかのテストは
mysqladmin --socket=/path/to/socket version