MeWrite Docs

Too many connections

MySQLの同時接続数が上限に達した場合に発生するエラー

概要

Too many connections は、MySQLサーバーへの同時接続数が設定された上限値(max_connections)に達した場合に発生するエラーです。アクセス集中時やコネクションリークが原因で発生します。

エラーメッセージ

ERROR 1040 (HY000): Too many connections
SQLSTATE[HY000] [1040] Too many connections
PDOException: SQLSTATE[HY000] [1040] Too many connections

原因

  1. アクセス集中: 同時アクセスが急増した
  2. コネクションリーク: 接続が正しくクローズされていない
  3. max_connectionsが低い: デフォルト値(151)が不足
  4. スロークエリ: 遅いクエリが接続を占有
  5. コネクションプールの設定不備: プールサイズが大きすぎる

解決策

1. 現在の接続状況を確認

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
-- 最大接続数を確認
SHOW VARIABLES LIKE 'max_connections';

-- 現在の接続数を確認
SHOW STATUS LIKE 'Threads_connected';

-- これまでの最大同時接続数
SHOW STATUS LIKE 'Max_used_connections';

-- 接続一覧を表示
SHOW PROCESSLIST;

-- 詳細な接続一覧
SHOW FULL PROCESSLIST;

2. max_connectionsを増やす

一時的に変更(再起動で戻る):

1
SET GLOBAL max_connections = 500;

永続的に変更(my.cnf / my.ini):

1
2
[mysqld]
max_connections = 500
1
2
# 設定を反映
sudo systemctl restart mysql

3. 不要な接続を切断

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
-- 特定の接続を切断
KILL <process_id>;

-- Sleep状態の接続を確認
SELECT * FROM information_schema.processlist
WHERE command = 'Sleep'
ORDER BY time DESC;

-- 長時間Sleepの接続を一括切断(注意して実行)
SELECT CONCAT('KILL ', id, ';')
FROM information_schema.processlist
WHERE command = 'Sleep' AND time > 300;

4. wait_timeoutを調整

1
2
3
4
5
6
7
-- 現在の設定を確認
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';

-- タイムアウトを短くする(秒)
SET GLOBAL wait_timeout = 300;
SET GLOBAL interactive_timeout = 300;

my.cnf:

1
2
3
[mysqld]
wait_timeout = 300
interactive_timeout = 300

5. アプリケーション側でコネクションプールを設定

Laravel (config/database.php):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
'mysql' => [
    'driver' => 'mysql',
    // ...
    'options' => [
        PDO::ATTR_PERSISTENT => false,
    ],
    'pool' => [
        'min' => 2,
        'max' => 10,
    ],
],

Django (settings.py):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        # ...
        'CONN_MAX_AGE': 600,  # 接続の再利用時間(秒)
        'OPTIONS': {
            'connect_timeout': 10,
        },
    }
}

Node.js (mysql2):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
const mysql = require('mysql2');

const pool = mysql.createPool({
    host: 'localhost',
    user: 'user',
    password: 'password',
    database: 'mydb',
    connectionLimit: 10,      // プールの最大接続数
    queueLimit: 0,            // 待機キューの上限
    waitForConnections: true, // 接続待ちを許可
});

6. コネクションリークを防ぐ

PHP:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// ❌ 間違い:接続がクローズされない
$pdo = new PDO($dsn, $user, $pass);
// 処理...
// 接続を閉じていない

// ✅ 正しい:明示的にクローズ
$pdo = new PDO($dsn, $user, $pass);
try {
    // 処理...
} finally {
    $pdo = null; // 接続をクローズ
}

Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# ❌ 間違い
conn = mysql.connector.connect(...)
cursor = conn.cursor()
# 処理...

# ✅ 正しい:with文を使用
import mysql.connector

with mysql.connector.connect(...) as conn:
    with conn.cursor() as cursor:
        cursor.execute("SELECT * FROM users")
        # 自動的にクローズされる

7. 監視を設定

1
2
3
4
5
-- 接続数の監視クエリ
SELECT
    @@max_connections AS max_connections,
    (SELECT COUNT(*) FROM information_schema.processlist) AS current_connections,
    (SELECT COUNT(*) FROM information_schema.processlist WHERE command = 'Sleep') AS sleeping_connections;

推奨設定値の目安

サーバースペックmax_connections備考
小規模(1-2GB RAM)100-200デフォルト付近
中規模(4-8GB RAM)300-500Webアプリ向け
大規模(16GB+ RAM)500-1000高負荷環境

MySQL の他のエラー

最終更新: 2025-12-08