1436 - переполнение стека потоков: используется 6136 байт из стека 131072 байт и необходимо 128000 байт.
Ошибка 1436 соответствует ER_STACK_OVERRUN_NEED_MORE в коде mysql 5.1:
malff@linux-8edv:include> pwd
/home/malff/BZR_TREE/mysql-5.1/include
malff@linux-8edv:include> grep 1436 mysqld_error.h
#define ER_STACK_OVERRUN_NEED_MORE 1436
Код печати, в котором обнаружена ошибка, находится в sql / sql_parse.cc, функция 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.
Вызов check_stack_overrun (), который пытается зарезервировать 128000 байт, происходит из:
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:
malff@linux-8edv:sql> pwd
/home/malff/BZR_TREE/mysql-5.1/sql
malff@linux-8edv: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, не зависит от триггера комсама по себе сложность или содержание / структура задействованных таблиц.
В чем вопрос real , я думаю, почему в thread_stack только 128K (131072).
Серверная переменная с именем 'thread_stack' реализована в C как 'my_thread_stack_size' в sql / mysqld.cc:
{"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
Таким образом, по умолчанию размер стека должен составлять 192 КБ (32 бита) или 256 КБ (64-битная архитектура).
Во-первых, проверьте, как был скомпилирован двоичный файл mysqld, чтобы узнать, какое значение по умолчанию:
malff@linux-8edv:sql> pwd
/home/malff/BZR_TREE/mysql-5.1/sql
malff@linux-8edv:sql> ./mysqld --no-defaults --verbose --help | grep thread_stack
...
--thread_stack=# The stack size for each thread.
thread_stack 262144
В моей системе я получил 256 КБ на 64-битной платформе.
Если естьэто разные значения, может быть, кто-то собирает сервер с разными параметрами компиляции, такими как -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 (теоретически, читая код, я сам никогда ее не видел).
Надеюсь, это ответит на вопрос.
С уважением, - МаркAlff
Обновление (2014-03-11), чтобы сделать "как исправить" более очевидным.
По всей вероятности, это значение по умолчанию для файла thread_stackбыло изменено в файле my.cnf.
Как исправить это тривиально, найдите, где в файле my.cnf задано значение thread_stack, и либо удалите настройку (доверяя коду сервера обеспечить достойное значение по умолчанию)значение, чтобы это не повторилось в следующий раз) или увеличьте размер стека.