1436-スレッドスタックオーバーラン:131072バイトスタックで6136バイトが使用され、128000バイトが必要です。
エラー1436は、mysql 5.1コードのER_STACK_OVERRUN_NEED_MOREに対応します:
[email protected]:include> pwd
/home/malff/BZR_TREE/mysql-5.1/include
[email protected]:include> grep 1436 mysqld_error.h
#define ER_STACK_OVERRUN_NEED_MORE 1436
表示されたエラーを出力するコードは、sql / sql_parse.cc、function check_stack_overrun()にあります:
bool check_stack_overrun(THD *thd, long margin,
uchar *buf __attribute__((unused)))
{
long stack_used;
DBUG_ASSERT(thd == current_thd);
if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
(long) (my_thread_stack_size - margin))
{
char ebuff[MYSQL_ERRMSG_SIZE];
my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
stack_used, my_thread_stack_size, margin);
my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
表示された値から、マージンは128000、my_thread_stack_sizeは131072です。
128000バイトを予約しようとするcheck_stack_overrun()の唯一の呼び出しは、次のとおりです。
bool
sp_head::execute(THD *thd)
{
/* Use some extra margin for possible SP recursion and functions */
if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
DBUG_RETURN(TRUE);
STACK_MIN_SIZEの値は16000です:
[email protected]:sql> pwd
/home/malff/BZR_TREE/mysql-5.1/sql
[email protected]:sql> grep STACK_MIN_SIZE *.h
mysql_priv.h:#define STACK_MIN_SIZE 16000 // Abort if less stack during eval.
これまでのところ、サーバーではすべてが期待どおりに機能しています。
- コードは、sp_head::executeで実装されるトリガーを実行します。
- MySQLランタイムは、スタックに少なくとも128000バイトがあることを確認します
- このチェックは失敗し(当然のことながら)、トリガーの実行はエラーで終了します。
MySQLトリガーの実行に必要なスタックの量は、トリガーの複雑さ自体、または関連するテーブルのコンテンツ/構造に依存しません。
本物 問題は、なぜthread_stackが128K(131072)しかないのかということです。
'thread_stack'という名前のサーバー変数は、Cではsql /mysqld.ccの'my_thread_stack_size'として実装されています:
{"thread_stack", OPT_THREAD_STACK,
"The stack size for each thread.", &my_thread_stack_size,
&my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
1024L*128L, ULONG_MAX, 0, 1024, 0},
1024L * 128Lは、このパラメーターの最小値です。デフォルト値はDEFAULT_THREAD_STACKで、include / my_pthread.h:
で定義されています。#ifndef DEFAULT_THREAD_STACK
#if SIZEOF_CHARP > 4
/*
MySQL can survive with 32K, but some glibc libraries require > 128K stack
To resolve hostnames. Also recursive stored procedures needs stack.
*/
#define DEFAULT_THREAD_STACK (256*1024L)
#else
#define DEFAULT_THREAD_STACK (192*1024)
#endif
#endif
したがって、デフォルトでは、スタックサイズは192K(32ビット)または256K(64ビットアーキテクチャ)である必要があります。
まず、mysqldバイナリがどのようにコンパイルされたかを確認し、デフォルト値を確認します。
[email protected]:sql> pwd
/home/malff/BZR_TREE/mysql-5.1/sql
[email protected]:sql> ./mysqld --no-defaults --verbose --help | grep thread_stack
...
--thread_stack=# The stack size for each thread.
thread_stack 262144
私のシステムでは、64ビットプラットフォームで256Kを取得しました。
値が異なる場合は、誰かが-DDEFAULT_THREAD_STACK(またはソースを変更しただけ)などの異なるコンパイルオプションを使用してサーバーを構築している可能性があります...その場合、バイナリはどこから来ているのか疑問に思います。
次に、my.cnfで、構成ファイル自体に提供されているデフォルト値を確認します。値をthread_stackに明示的に(そして低い値で)設定する行は、間違いなくエラーを引き起こします。
最後に、サーバーログファイルで次のようなエラーがないか確認します(sql / mysqld.ccを参照):
sql_print_warning("Asked for %lu thread stack, but got %ld",
my_thread_stack_size, (long) stack_size);
サーバーコードの呼び出し:
- スタックサイズを設定するためのpthread_attr_setstacksize()
- pthread_attr_getstacksize()を使用して、スレッドが実際に持っているスタックの量を確認し、pthreadライブラリの使用量が少ない場合はログに文句を言います。
簡単に言うと、サーバーに付属しているデフォルト値と比較してthread_stackが小さすぎるためにエラーが発生します。これは、次の場合に発生する可能性があります。
- さまざまなコンパイルオプションを使用してサーバーのカスタムビルドを実行する場合
- my.cnfファイルのデフォルト値を変更する場合
- pthreadライブラリ自体に問題が発生した場合(理論的には、コードを読んだことから、私はそれを自分で見たことがありません)。
これが質問に答えることを願っています。
よろしく、-マークアルフ
「修正方法」をより明確にするための更新(2014-03-11)。
おそらく起こっていることは、thread_stackファイルのデフォルト値がmy.cnfファイルで変更されたことです。
それを修正する方法は簡単です。my.cnfファイルのどこにthread_stackが設定されているかを見つけ、設定を削除するか(サーバーコードを信頼して適切なデフォルト値を提供するため、次回はこれが再び発生しません)、スタックを増やします。サイズ。
アップデート(2021-04-28)、thread_stackの出所を確認してください:
テーブルperformance_schema.variables_info
を使用します 与えられた変数がどこから来たのかを知るために。
mysql> select * from variables_info where VARIABLE_NAME = 'thread_stack';
+---------------+-----------------+---------------+-----------+----------------------+----------+----------+----------+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH | MIN_VALUE | MAX_VALUE | SET_TIME | SET_USER | SET_HOST |
+---------------+-----------------+---------------+-----------+----------------------+----------+----------+----------+
| thread_stack | COMPILED | | 131072 | 18446744073709550592 | NULL | NULL | NULL |
+---------------+-----------------+---------------+-----------+----------------------+----------+----------+----------+
1 row in set (0.01 sec)
ここでのデフォルトは工場出荷時の値です(mysqldバイナリでコンパイルされます)。
別の例:
mysql> select * from variables_info where VARIABLE_NAME = 'thread_stack';
+---------------+-----------------+----------------------------------------------------------------+-----------+----------------------+----------+----------+----------+
| VARIABLE_NAME | VARIABLE_SOURCE | VARIABLE_PATH | MIN_VALUE | MAX_VALUE | SET_TIME | SET_USER | SET_HOST |
+---------------+-----------------+----------------------------------------------------------------+-----------+----------------------+----------+----------+----------+
| thread_stack | EXPLICIT | /home/malff/CODE/GIT/GIT_TRUNK/build-dbg/mysql-test/var/my.cnf | 131072 | 18446744073709550592 | NULL | NULL | NULL |
+---------------+-----------------+----------------------------------------------------------------+-----------+----------------------+----------+----------+----------+
1 row in set (0.00 sec)
ここで、thread_stackは、報告されたmy.cnfファイルに設定されています。
Refman:
https://dev.mysql .com / doc / refman / 8.0 / en / performance-schema-variables-info-table.html