Mac OS Xでmysqlを立てたらTCP/IPで接続できなかった

Mac OS Xでmysqlを立てたらTCP/IPで接続できなかった。

最近はMacで開発環境を構築しています岡田洋一です、こんにちは。
Macは便利で良いですね。いわゆるノマド的な開発も可能でとても良いです。
さてそんなMacなのですがその中に開発環境を構築してやる必要があります。
僕の場合だいたいは apache + mysql + php あたりになります。
さてその中のmysqlが今回は問題を引き起こしてくれました。

TCP/IPで繋がらないんですね。


shell> mysql -h localhost -u root

なんてやってみてもダメですし

shell> netstat -nat | grep 3306

(注) portの待ち受け確認にはいくつかの方法があります。linux系ですと netstat -plnt(?) のようなオプションもありますが、macのdarwinなpsとは互換性がありません。-natオプションはlinux系でも動くのでコチラを利用しています。FreeBSDを利用していた頃はsockstatをよく使っていましたがコチラもOS依存です。

とやってみるとそもそも3306で待ち受けをしていない。netstat -nat というのはtcpで待ち受けをしているポート番号一覧を出してくれて、grepでmysqlの標準待ち受けポートの3306があるかどうかを調べています。

ポート3306でそもそも待ち受けをしていないので、iptableやmysqlのユーザの権限が原因ではなさそうです。

原因として濃厚なのはmy.cnfの記述が真っ先に疑われます。

今回のmysqlはmac portsからインストールしたので、そのmy.cnfは /opt/local/etc/ にあります。

ややこしかったのはこの /opt/local/etc の中にmysql5とmysql51との両方が存在したことでした。

まずはmac portsでインストール済みパッケージの確認


shell> port installed | grep mysql

mysql5 @5.1.68_0
 mysql5 @5.1.70_0 (active)
 mysql51 @5.1.68_0
 mysql51 @5.1.70_0 (active)
 mysql51-server @5.1.68_0
 mysql51-server @5.1.70_0 (active)
 mysql_select @0.1.2_0 (active)
 php5-mysql @5.3.23_0+mysqlnd
 php5-mysql @5.3.26_0+mysqlnd (active)

うーん、結構入っている上にすべてがactiveになっていますね。mac portsにはactive/inactive意外にもload/unloadという状態があります。acitve/inactiveはそもそもそのパッケージが有効か否か、load/unloadはservice startされるかどうか、という感じだそうです。

activeなパッケージの場合、/Library/LaunchDaemons/ に起動スクリプト(実際には起動オプション)がありますので、そちらからパッケージ名を特定しようとしてみます。


shell> ls /Library/LaunchDaemons/*mysql*

/Library/LaunchDaemons/org.macports.mysql51-server.plist

どうやらmysql51-serverのようですね。では実際のmy.cnfは…、というと、通例ですとこのplistファイルに記述されたりするのですがmysql51-serverでは記載がない。バイナリで決めうちなのか、不明ということでした。

プロセスの起動時引数で確認できるかと思い、psで確認しようとしてみました。–conf=/usr/local/etc/my.cnf なんて書いてあるかもしれないですし。


shell> ps auxww | grep mysql
root 3893 0.0 0.0 2465328 1112 ?? Ss 11:20AM 0:00.01 /opt/local/bin/daemondo --label=mysql51-server --start-cmd /opt/local/lib/mysql51/bin/mysqld --user=_mysql ; --pid=exec

が、結局ドコのmy.cnfを利用しているかは分からない!

しょうが無いので実際に書き換えて,ドコが反映されるかを調べてみました。


/opt/local/etc/mysql51/my.cnf のsockでunix ドメインソケットの名前を変更してみました。

shell> grep sock /opt/local/etc/mysql51/my.cnf

socket = /tmp/mysqlnosocketdayo.sock

socketの設定を変更してmysqldを再起動。mac portsで管理されるパッケージの再起動は未だによく分かってないのですが、僕は以下のようにして再起動しています。


shell> sudo sh -c 'port unload mysql51-server; port load mysql51-server;'; ps auxww| grep mysq

再起動できたかどうか、エラーが出た場合なんかにはあまりエラーメッセージを出してくれないので注意が必要です。

で、socketの書き換えはうまく成功していました。ということは利用されているコンフィグは /opt/local/etc/mysql51/my.cnf で間違いがないようです。

さてmy.cnfを確認してみるのですが、特に変な記述はありません。tcp/ipで待ち受けをしていない時にありがちなのは

  • port行が無い
  • bind-address行が無い (無くても待ち受けしてくれます。listen addressを別個で指定したい場合に利用するものですね。127.0.0.1などのループバックアドレスを指定するとローカルホストからしか繋がらないです。注意。)
  • skip-networkが有効になっている

といったところでしょうか。何にせよ netstat -natで待ち受けされていないのですからこの辺りが疑わしいわけです。

が、今回の場合ではどの条件にも合致しそうにない。ホトホト困ってしまいました。IRCで質問したり(moderate権限が無くて発言できない!)、知っていそうな人に質問したり(友達がいなかった!)したのですがダメ。結局数ヶ月をおいてしまう事になりました。

が、一念発起してさらに調べたところ、 /opt/local/etc/mysql51/ にmy.cnf以外のファイルがあることを再認識。

ファイル名はmacports-default.cnf なんていう、macportsでインストールしたらこのファイルをサンプルに津かってね、っぽい名前のファイルがありました。

サンプルコンフィグかな、なんて見過ごしていたんですが中身を確認してみると


shell> more /opt/local/etc/mysql51/macports-default.cnf

# WARNING! ANY CHANGES TO THIS FILE WILL BE LOST ON UNINSTALL/UPGRADES!
# Make your changes to /opt/local/etc/mysql51/my.cnf
# YOU HAVE BEEN WARNED!

# MacPorts default options
[mysqld]
# skip-networking so multple mysql server ports can be loaded
# without each competing for port 3306.
skip-networking

最終行にしっかりと、skip-netwrokingとかいてある…!消して再起動すると


shell> sudo sh -c 'port unload mysql51-server; port load mysql51-server;'

shell>  netstat -nat | grep 3306

tcp4 0 0 *.3306 *.* LISTEN

(注) mysqlの起動終了からポート待ち受けまでの間、立ち上げ処理などでタイムラグがあります。なのでワンライナーでつなげて記述すると待ち受け確認できません。sleepを挟むなどしましょう。

リッスンしてる!!!!

というわけでめでたく繋がるようになりました。めでたしめでたし。

「Mac OS Xでmysqlを立てたらTCP/IPで接続できなかった」への2件のフィードバック

  1. 岡田様

    javaのプログラムでMySQLにアクセスを試みていたのですがなかなかうまくいかず、5日程ずっと原因を探っていました。

    こちらの記事にあるようにmy.cnfのskip-netwrokingをコメントアウトを試したところうまくアクセスすることが出来ました。

    涙がでるほど嬉しかったです。
    本当に有用な記事をありがとうございます!

コメントを残す