Я искал ответ на этот вопрос, но нигде не нашел.
Я хочу уменьшить использование памяти при каждом подключении к базе данных. Вот что сейчас говорит тюнер mysql об использовании памяти одной из моих баз данных:
[--] Physical Memory : 985.2M
[--] Max MySQL memory : 950.4M
[--] Other process memory: 0B
[--] Total buffers: 292.0M global + 18.8M per thread (35 max threads)
[--] P_S Max memory usage: 0B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 310.8M (31.55% of installed RAM)
[!!] Maximum possible memory usage: 950.4M (96.47% of installed RAM)
Вы можете видеть, что использование памяти на поток довольно велико. 18,8 млн. А вот вывод одного из моих других серверов:
[--] Total buffers: 400.0M global + 2.8M per thread (250 max threads)
Вы можете видеть, что использование памяти здесь намного ниже (всего 2,8 млн), поэтому у меня может быть гораздо больше подключений к базе данных.
Я попытался выяснить, какая переменная контролирует использование памяти для каждого потока, но ничего не нашел. Я думал, что это связано с sort_buffer_size или read_buffer_size, но когда я меняю одну из этих переменных, использование каждого потока, похоже, не падает.
Мне кажется, что это не то, что я вообще могу изменить и, вероятно, рассчитывается на основе фактического использования памяти на поток?
Могу ли я что-нибудь сделать, чтобы уменьшить использование буферной памяти на поток?
Изменить (2020-06-10): разница между этими двумя базами данных заключается в том, что первая - это версия MariaDB 10.4.12, а вторая - MariaDB 10.1.38. Если я сравниваю такие переменные, как sort_buffer_size, read_buffer_size, key_buffer_size и другие, упомянутые в комментариях, все, что я вижу, это то, что для них установлены одинаковые значения.
Это вымышленное число. Он основан на множестве пессимистических предположений. Тем не менее, в некоторых действительно экстремальных ситуациях это недооценка. (Для этой метрики нет хорошего выражения.)
Похоже, у вас 1 ГБ ОЗУ. Это очень небольшая сумма, но она жизнеспособна.
(Примечание: когда у вас заканчивается ОЗУ, происходит подкачка. Но, поскольку MariaDB оптимизирована с учетом отсутствия подкачки, подкачка приводит к действительно плохой производительности.)
У вас есть другие приложения, работающие на этом 1 ГБ? Если так, то дела обстоят еще сложнее.
Сначала проверьте innodb_buffer_pool_size
. 200M может быть слишком большим. max_connections
должно быть не больше 20. Они должны быть меньше 10M: tmp_table_size, max_heap_table_size, sort_buffer_size, innodb_log_buffer_size, read_buffer_size, read_rnd_buffer_size.
Если вам нужен дальнейший анализ, см. http://mysql.rjweb.org/doc.php/mysql_analysis#tuning
Ладно, после некоторого расследования я наконец понял, почему эти два числа такие разные.
Дело в том, что я использовал старую версию mysqltuner.pl на сервере, где максимальное использование памяти на поток составляло всего 2,8 МБ. А 6 месяцев назад mysqltuner.pl также начал использовать max_allowed_packet значение переменной в расчете использования на поток, которое добавляет дополнительные 16 МБ и достигает 18,8 МБ. Вот изменения на github: https://github.com/major/MySQLTuner-perl/commit/c5765f02133259b40d9932eb7d35ba5c1665bad9 После запуска обновленной версии mysqltuner.pl использование оперативной памяти отображается следующим образом:
[--] Total buffers: 400.0M global + 18.8M per thread (250 max threads)
Это переменные, которые используются для расчета использования буфера на поток (для относительно новых версий MariaDB):
read_buffer_size,
read_rnd_buffer_size,
sort_buffer_size,
thread_stack,
max_allowed_packet,
join_buffer_size
Только @Wilson Hauck упомянул переменную max_allowed_packet;)
И вот запрос на проверку этих значений, если это кому-то нужно:
SHOW GLOBAL VARIABLES WHERE variable_name IN('read_buffer_size', 'read_rnd_buffer_size', 'sort_buffer_size', 'thread_stack', 'max_allowed_packet', 'join_buffer_size');
Итак, после всех этих исследований я понял, что у меня слишком большое количество разрешенных подключений к базе данных на втором сервере (250). При использовании всего моя БД могла бы использовать 5 ГБ ОЗУ, в то время как у меня в этой системе только 2 ГБ.
Актуальный ответ на первоначальный вопрос: Поэтому, если я хочу уменьшить использование памяти для каждого потока или для каждого соединения (как некоторые из вас упомянули), мне, вероятно, придется снизить значение max_allowed_packet, но я не уверен, что это хорошая идея.
Спасибо всем за помощь.
Педантичный ответ на ваш вопрос: thread_stack_size контролирует память на поток.
Любая другая переменная не имеет ничего общего с потоками, хотя max_connections ограничивает количество потоков, но даже после тысяч подключений вы все равно можете использовать один поток (thread_handling = pool-of-threads, thread_pool_max_threads = 1), хотя я не рекомендую это.