Назад | Перейти на главную страницу

MariaDB снижает использование буферной ОЗУ на поток

Я искал ответ на этот вопрос, но нигде не нашел.

Я хочу уменьшить использование памяти при каждом подключении к базе данных. Вот что сейчас говорит тюнер 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), хотя я не рекомендую это.