症状
MySQLに接続しようとすると ERROR 2003 (HY000): Can't connect to MySQL server on 'hostname' (111 "Connection refused") が表示される
結論:まずこれを確認
- MySQLプロセスが起動しているか確認する
- MySQLが正しいポート(デフォルト3306)でリッスンしているか確認する
- bind-addressの設定がアクセス元を許可しているか確認する
トラブルシューティングフロー
flowchart TD
A[Connection refused発生] --> B{MySQLプロセス起動中?}
B -->|No| C[MySQLを起動する]
B -->|Yes| D{ポート3306でリッスン?}
D -->|No| E[my.cnfのport設定を確認]
D -->|Yes| F{bind-address設定は?}
F -->|127.0.0.1のみ| G[bind-addressを変更]
F -->|0.0.0.0| H{ファイアウォール確認}
H -->|ブロック| I[ファイアウォール設定変更]
H -->|許可済み| J[MySQLユーザー権限確認]
C --> K[起動ログを確認]
K -->|エラーあり| L[エラー内容に応じた対処]
K -->|正常起動| D
よくある原因
- MySQLプロセスが停止している - サーバー再起動後に自動起動していない
- bind-addressが127.0.0.1に設定されている - ローカル以外からの接続を受け付けない
- ポート番号が異なる - 設定変更やバージョン違いで3306以外を使用
- ファイアウォールでブロックされている - iptables/firewalld/ufw等で3306が閉じている
- ソケットファイルの問題 - /var/lib/mysql/mysql.sock が存在しない・権限不正
- MySQLが起動途中でクラッシュしている - ディスク容量不足やメモリ不足
- SELinuxによるブロック - SELinuxが有効な環境でポリシー違反
確認手順
ステップ1: MySQLプロセスを確認する
# systemdの場合
systemctl status mysql
# または
systemctl status mysqld
# プロセス直接確認
ps aux | grep mysql
🔍 チェックポイント: active (running) と表示されれば起動中
ステップ2: リッスンポートを確認する
# netstatで確認
netstat -tlnp | grep mysql
# ssで確認(netstatがない場合)
ss -tlnp | grep mysql
# lsofで確認
lsof -i :3306
🔍 チェックポイント: 0.0.0.0:3306 または :::3306 が表示されればリモート接続可能
ステップ3: bind-address設定を確認する
# 設定ファイルを確認
grep bind-address /etc/mysql/mysql.conf.d/mysqld.cnf
# または
grep bind-address /etc/my.cnf
🔍 チェックポイント: リモート接続が必要なら bind-address = 0.0.0.0 である必要がある
ステップ4: ファイアウォールを確認する
# firewalldの場合
firewall-cmd --list-ports
firewall-cmd --list-services
# ufwの場合
ufw status
# iptablesの場合
iptables -L -n | grep 3306
🔍 チェックポイント: ポート3306が許可されていること
ステップ5: MySQLエラーログを確認する
# ログファイルの場所を確認
mysql --help | grep "Default options" -A 1
# エラーログを確認
tail -100 /var/log/mysql/error.log
# または
tail -100 /var/log/mysqld.log
🔍 チェックポイント: [ERROR] の行がないか確認する
ステップ6: ソケットファイルを確認する
# ソケットファイルの存在確認
ls -la /var/lib/mysql/mysql.sock
# または
ls -la /tmp/mysql.sock
🔍 チェックポイント: ファイルが存在し、mysqlユーザーが所有していること
NG行動(やってはいけないこと)
- skip-grant-tablesで起動して放置する - セキュリティリスクが極めて高い
- bind-address=0.0.0.0に変更してファイアウォールを開けずに終わる - 接続できない原因が変わるだけ
- エラーログを確認せずに再起動を繰り返す - 根本原因が分からないまま時間を浪費
- 本番環境でSELinuxを無効化する - 一時的な回避策としても危険
- 権限なしでmysqld_safeを直接実行する - プロセス管理が複雑になる
よくある質問(FAQ)
Q1: ローカルからは接続できるがリモートから接続できない場合は?
A: bind-addressが127.0.0.1になっている可能性が高い。0.0.0.0に変更し、MySQLを再起動する。併せてファイアウォールで3306ポートを許可する。
Q2: MySQLは起動しているのにソケットエラーが出る場合は?
A: 接続時に指定しているソケットパスと、実際のソケットファイルの場所が異なる。mysql --socket=/var/lib/mysql/mysql.sock のように明示的に指定する。
Q3: Docker環境でConnection refusedが出る場合は?
A: コンテナのポートマッピング(-p 3306:3306)を確認する。また、ホストからはlocalhostではなく127.0.0.1を指定する必要がある場合がある。
関連するエラー・症状
準備中
解決しない場合
- 公式ドキュメント: MySQL 8.0 Connection Issues
- 確認すべきログ:
/var/log/mysql/error.log/var/log/mysqld.logjournalctl -u mysql
- 次に調べるキーワード:
MySQL Access denied for userMySQL socket file not foundMySQL server has gone away