MySQL ERROR 1436の修正:Thread Stack Overrunの解決方法

intermediate🗄️ MySQL2026-07-11| MySQL 5.7, MySQL 8.0+, MariaDB, Ubuntu/Debian, CentOS, Windows, Docker Containers

Error Message

ERROR 1436 (HY000): Thread stack overrun: 246144 bytes used
#mysql#データベース#ストアドプロシージャ#トラブルシューティング

クイック解決策

ERROR 1436を解消するには、設定ファイルでthread_stackのサイズを増やす必要があります。最近のデータベースワークロードの多くは、192KBや256KBといった古いデフォルト値では不足することがあります。これを512KBまたは1MBに増やすことで、通常は即座にクラッシュを止めることができます。

  • 設定ファイル(通常は /etc/mysql/my.cnf または /etc/my.cnf)を開きます。
  • [mysqld] ブロックを探します。
  • 次の行を追加または編集します:thread_stack = 512K
  • サービスを再起動します:sudo systemctl restart mysql

発生原因

スレッドスタックは、MySQLが個々の接続に割り当てる「作業スペース」のようなものだと考えてください。このメモリはローカル変数、関数呼び出し、および複雑なロジックを処理します。クエリがその作業スペースの許容量を超えるデータを詰め込もうとすると、システム全体のクラッシュを防ぐためにエンジンが Thread stack overrun をスローします。

エラーメッセージにある 246144 bytes used という数値は大きなヒントになります。上限が256KB(262,144バイト)に設定されているシステムでは、246KBを使用するとオペレーティングシステム自体のオーバーヘッドのための余裕がほとんど残りません。実質的にメモリの限界値に達している状態です。

主な原因は以下の通りです:

  • 深いネスト: 大規模で多層構造のドキュメントに対して JSON_EXTRACT などのJSON関数を使用している。
  • 重いトリガー: 1つの更新が他の5つのテーブルに連鎖反応を引き起こしている。
  • 再帰: 明確な終了条件なしに自分自身を繰り返し呼び出すストアドプロシージャ。

ステップバイステップの解決手順

1. 現在の制限値を確認する

変更を加える前に、サーバーが現在どのような設定で動作しているかを確認します。MySQLターミナルで以下のコマンドを実行してください。

SHOW VARIABLES LIKE 'thread_stack';

結果が 262144 であれば、256KBで動作しています。64ビットシステムでは、複雑なクエリを処理するにはこの値は小さすぎることが多いです。

2. 設定ファイルを更新する

thread_stack 変数は静的(static)な変数です。サーバーの稼働中に変更することはできず、再起動が必須となります。

Linuxユーザー (Ubuntu/Debian/CentOS):

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# ファイルが存在しない場合は、以下を試してください:
sudo nano /etc/my.cnf

Windowsユーザー:

インストールフォルダ内の my.ini を開きます。通常は C:\ProgramData\MySQL\MySQL Server 8.0\my.ini にあります。

Dockerユーザー:

docker-compose.yml を使用している場合は、コマンドライン引数に設定を追加します。

services:
  db:
    image: mysql:8.0
    command: --thread_stack=512K

3. 適用と確認

新しい設定を読み込むために MySQL デーモンを再起動します:

# Linux
sudo systemctl restart mysql

# Windows
# 'サービス' (Services.msc) または MySQL Notifier から再起動してください

再起動後、再度 SHOW VARIABLES コマンドを実行してください。524288(512Kの場合)または 1048576(1Mの場合)と表示されるはずです。

予防的なコードの最適化

スタックサイズの増量は有効な解決策ですが、不適切なコードを隠してしまう可能性もあります。スタックを2MBに増やしても依然としてエラーが出る場合は、無限ループが発生している可能性が高いです。これは通常、ストアドプロシージャで起こります。

トリガーAがテーブルBを更新し、トリガーBがテーブルAを更新するように設定されている「ピンポン」ロジックがないか確認してください。これによりループが発生し、ミリ秒単位でスタックを消費します。また、すべての再帰プロシージャにループを抜けるための適切な IF 文があることを確認してください。

メモリ計算に関する警告

すべての接続が独自のスタックを持ちます。もし max_connections = 500thread_stack = 1M に設定した場合、MySQL はこれらのスタック専用に 500MB の RAM を確保します。2GB程度の小規模な VPS では、これが OOM (Out of Memory) エラーの原因になる可能性があります。スタックは実際に必要な分だけ増やすようにしてください。多くのエンタープライズアプリケーションでは 512KB が「スイートスポット(最適値)」です。

関連資料

Related Error Notes