Ответ, предоставленный chaos , был правильным: запросы ограничены количеством SELECT / UNION, а не общим количеством символов. Я попытался удалить все тексты из своего запроса, уменьшив его с 1 МБ до 100 КБ, но MySQL все равно отказался его принять. Но как только я уменьшил количество строк до предела, который мы пытаемся найти, запрос начал работать.
И вот полный ответ, который я вывел из наблюдений, экспериментов и немного математического шаманизма.
По умолчанию MySQL значение для thread_stack
равно 286 720 bytes
, что означает 262 KiB
.
С этим значением я могу создать запрос с 4076 SELECTs
: одна база SELECT
+ 4075 UNIONs
.
4076
это почти 4096
, без 20
. Это означает, что кто-то украл число, равное 20 SELECTs
.
286 720 (262 KiB)
это почти 262 144 (256 KiB)
. Похоже, что MySQL хочет эту 24 576 (6 KiB)
для своих теневых целей.
Давайте разделим одно почти на другое почти: 262 144 / 4096 = 64
. Кажется, для одного SELECT
требуется 64 bytes
памяти.
Тогда мы можем изобрести формулу: (thread_stack - shady MySQL hoard - stolen 20 SELECTs) / bytes per SELECT = SELECTs available to us
Если по умолчанию 286720 байт: (286 720 - 24 576 - 1 280) / 64 = 4076
Затем я проверил это с настройкой thread_stack=131072
в файле конфигурации. Это 128 KiB
. Вот математика: (131 072 - 24 576 - 1 280) / 64 = 1644
Я отредактировал свой запрос, чтобы он содержал 1644 SELECTs
. Он работал без проблем.
Затем добавил еще один маленький UNION + SELECT и сразу получил:
ERROR 1436 (HY000) в строке 1: Переполнение стека потоков: использовано 111088 байт из стек 131072 байта и требуется 20000 байтов. Используйте mysqld --thread_stack = #, чтобы указать больший стек.
Похоже, что сейчас формула работает правильно. Но сработает ли это в будущем - возможно, но это не более чем предположение.