Насколько большим должен быть mysql innodb_buffer_pool_size?


170

У меня есть занятая база данных только с таблицами InnoDB, размер которой составляет около 5 ГБ. База данных работает на сервере Debian с использованием SSD-дисков, и я установил максимальное число соединений = 800, которые иногда насыщают и приводят к остановке сервера. Среднее количество запросов в секунду составляет около 2.5К. Поэтому мне нужно оптимизировать использование памяти, чтобы освободить место для максимально возможных подключений.

Я видел предположения, что innodb_buffer_pool_size должен быть до 80% от общего объема памяти. С другой стороны, я получаю это предупреждение из скрипта tuning-primer:

Max Memory Ever Allocated : 91.97 G
Configured Max Per-thread Buffers : 72.02 G
Configured Max Global Buffers : 19.86 G
Configured Max Memory Limit : 91.88 G
Physical Memory : 94.58 G

Вот мои текущие переменные innodb:

| innodb_adaptive_flushing                          | ON                                                                                                                     |
| innodb_adaptive_hash_index                        | ON                                                                                                                     |
| innodb_additional_mem_pool_size                   | 20971520                                                                                                               |
| innodb_autoextend_increment                       | 8                                                                                                                      |
| innodb_autoinc_lock_mode                          | 1                                                                                                                      |
| innodb_buffer_pool_instances                      | 1                                                                                                                      |
| innodb_buffer_pool_size                           | 20971520000                                                                                                            |
| innodb_change_buffering                           | all                                                                                                                    |
| innodb_checksums                                  | ON                                                                                                                     |
| innodb_commit_concurrency                         | 0                                                                                                                      |
| innodb_concurrency_tickets                        | 500                                                                                                                    |
| innodb_data_file_path                             | ibdata1:10M:autoextend                                                                                                 |
| innodb_data_home_dir                              |                                                                                                                        |
| innodb_doublewrite                                | ON                                                                                                                     |
| innodb_fast_shutdown                              | 1                                                                                                                      |
| innodb_file_format                                | Antelope                                                                                                               |
| innodb_file_format_check                          | ON                                                                                                                     |
| innodb_file_format_max                            | Antelope                                                                                                               |
| innodb_file_per_table                             | ON                                                                                                                     |
| innodb_flush_log_at_trx_commit                    | 2                                                                                                                      |
| innodb_flush_method                               | O_DIRECT                                                                                                               |
| innodb_force_load_corrupted                       | OFF                                                                                                                    |
| innodb_force_recovery                             | 0                                                                                                                      |
| innodb_io_capacity                                | 200                                                                                                                    |
| innodb_large_prefix                               | OFF                                                                                                                    |
| innodb_lock_wait_timeout                          | 50                                                                                                                     |
| innodb_locks_unsafe_for_binlog                    | OFF                                                                                                                    |
| innodb_log_buffer_size                            | 4194304                                                                                                                |
| innodb_log_file_size                              | 524288000                                                                                                              |
| innodb_log_files_in_group                         | 2                                                                                                                      |
| innodb_log_group_home_dir                         | ./                                                                                                                     |
| innodb_max_dirty_pages_pct                        | 75                                                                                                                     |
| innodb_max_purge_lag                              | 0                                                                                                                      |
| innodb_mirrored_log_groups                        | 1                                                                                                                      |
| innodb_old_blocks_pct                             | 37                                                                                                                     |
| innodb_old_blocks_time                            | 0                                                                                                                      |
| innodb_open_files                                 | 300                                                                                                                    |
| innodb_purge_batch_size                           | 20                                                                                                                     |
| innodb_purge_threads                              | 0                                                                                                                      |
| innodb_random_read_ahead                          | OFF                                                                                                                    |
| innodb_read_ahead_threshold                       | 56                                                                                                                     |
| innodb_read_io_threads                            | 4                                                                                                                      |
| innodb_replication_delay                          | 0                                                                                                                      |
| innodb_rollback_on_timeout                        | OFF                                                                                                                    |
| innodb_rollback_segments                          | 128                                                                                                                    |
| innodb_spin_wait_delay                            | 6                                                                                                                      |
| innodb_stats_method                               | nulls_equal                                                                                                            |
| innodb_stats_on_metadata                          | ON                                                                                                                     |
| innodb_stats_sample_pages                         | 8                                                                                                                      |
| innodb_strict_mode                                | OFF                                                                                                                    |
| innodb_support_xa                                 | ON                                                                                                                     |
| innodb_sync_spin_loops                            | 30                                                                                                                     |
| innodb_table_locks                                | ON                                                                                                                     |
| innodb_thread_concurrency                         | 4                                                                                                                      |
| innodb_thread_sleep_delay                         | 10000                                                                                                                  |
| innodb_use_native_aio                             | ON                                                                                                                     |
| innodb_use_sys_malloc                             | ON                                                                                                                     |
| innodb_version                                    | 1.1.8                                                                                                                  |
| innodb_write_io_threads                           | 4                                                                                                                      |

Дополнительное примечание, которое может иметь отношение: я вижу, что когда я пытаюсь вставить большой пост (скажем, более 10 КБ) из Drupal (который находится на отдельном веб-сервере) в базу данных, он длится вечно, и страница не возвращается правильно.

Что касается этого, мне интересно, какой должен быть мой innodb_buffer_pool_size для оптимальной производительности. Я ценю ваши предложения, чтобы установить этот и другие параметры оптимально для этого сценария.

Ответы:


252

Ваш innodb_buffer_pool_size огромен. Вы установили это на 20971520000. Это 19,5135 ГБ. Если у вас только 5 ГБ данных и индексов InnoDB, то у вас должно быть только около 8 ГБ. Даже это может быть слишком высоко.

Вот что вы должны сделать. Сначала запустите этот запрос

SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
(SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
FROM information_schema.tables WHERE engine='InnoDB') A;

Это даст вам RIBPS, рекомендуемый размер пула буферов InnoDB на основе всех данных и индексов InnoDB с дополнительными 60%.

Например

mysql>     SELECT CEILING(Total_InnoDB_Bytes*1.6/POWER(1024,3)) RIBPS FROM
    ->     (SELECT SUM(data_length+index_length) Total_InnoDB_Bytes
    ->     FROM information_schema.tables WHERE engine='InnoDB') A;
+-------+
| RIBPS |
+-------+
|     8 |
+-------+
1 row in set (4.31 sec)

mysql>

С этим выводом вы должны установить следующее в /etc/my.cnf

[mysqld]
innodb_buffer_pool_size=8G

Следующий, service mysql restart

После перезагрузки запустите mysql на неделю или две. Затем выполните этот запрос:

SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM
(SELECT variable_value PagesData
FROM information_schema.global_status
WHERE variable_name='Innodb_buffer_pool_pages_data') A,
(SELECT variable_value PageSize
FROM information_schema.global_status
WHERE variable_name='Innodb_page_size') B;

Это даст вам информацию о том, сколько фактических ГБ памяти используется данными InnoDB в пуле буферов InnoDB в данный момент.

Я писал об этом раньше: что установить innodb_buffer_pool и почему ..?

Вы можете просто выполнить этот DataGBзапрос прямо сейчас, а не перенастраивать, перезагружать и ждать неделю.

Это значение DataGBбольше похоже на то, насколько большим должен быть + буферный пул InnoDB + (процент, указанный в innodb_change_buffer_max_size). Я уверен, что это будет намного меньше, чем 20000M, которые вы зарезервировали прямо сейчас. Экономия в оперативной памяти может быть использована для настройки других вещей, таких как

ПЕРЕДАЧА № 1

Это очень важно отметить: время от времени InnoDB может потребовать дополнительные 10% сверх значения для innodb_buffer_pool_size . Вот что говорит MySQL Documentation по этому поводу :

Чем больше вы установите это значение, тем меньше потребуется дискового ввода-вывода для доступа к данным в таблицах. На выделенном сервере базы данных вы можете установить до 80% объема физической памяти компьютера. Будьте готовы уменьшить это значение, если возникнут следующие проблемы:

Конкуренция за физическую память может привести к подкачке в операционной системе.

InnoDB резервирует дополнительную память для буферов и управляющих структур, так что общее выделенное пространство примерно на 10% больше указанного размера.

Адресное пространство должно быть смежным, что может быть проблемой в системах Windows с библиотеками DLL, которые загружаются по определенным адресам.

Время инициализации буферного пула примерно пропорционально его размеру. На больших установках это время инициализации может быть значительным. Например, на современном сервере Linux x86_64 инициализация пула буферов 10 ГБ занимает примерно 6 секунд. См. Раздел 8.9.1, «Буферный пул InnoDB» .

ПЕРЕДАЧА № 2

Я вижу следующие значения в вашем my.cnf

| innodb_io_capacity                                | 200 |
| innodb_read_io_threads                            | 4   |
| innodb_thread_concurrency                         | 4   |
| innodb_write_io_threads                           | 4   |

Эти цифры не позволят InnoDB получить доступ к нескольким ядрам.

Пожалуйста, установите следующее:

[mysqld]
innodb_io_capacity = 2000
innodb_read_io_threads = 64
innodb_thread_concurrency = 0
innodb_write_io_threads = 64

Я уже писал об этом раньше в DBA StackExchange

Я только что ответил на такой вопрос в ServerFault, используя более краткую формулу :

SELECT CONCAT(CEILING(RIBPS/POWER(1024,pw)),SUBSTR(' KMGT',pw+1,1))
Recommended_InnoDB_Buffer_Pool_Size FROM
(
    SELECT RIBPS,FLOOR(LOG(RIBPS)/LOG(1024)) pw
    FROM
    (
        SELECT SUM(data_length+index_length)*1.1*growth RIBPS
        FROM information_schema.tables AAA,
        (SELECT 1.25 growth) BBB
        WHERE ENGINE='InnoDB'
    ) AA
) A;

1
Спасибо за этот великий пост! Ваша формула, начинающаяся с, SELECT (PagesData*PageSize)/POWER(1024,3) DataGB FROM...генерирует следующую ошибку в MySQL 5.7: « Функция« INFORMATION_SCHEMA.GLOBAL_STATUS »отключена; см. Документацию для« show_compatibility_56 » ». Будет ли у вас обновленная версия случайно?
Бенджамин

Я получаю 307 RIBPS и 264G. Это значит, что мне нужно 307 ГБ оперативной памяти?
E_Blue

Больше похоже на 264G. Но для этого у вас должно быть достаточно ОЗУ, иначе отдайте упомянутые 80% вашей ОЗУ mysql, в зависимости от того, что еще работает в системе.
Sjas

2
Величайший пост, который я когда-либо читал! У меня есть большая база данных около 3 ГБ. После прочтения вашего ответа / статьи скорость ссылок
возросла

4
@ Бенджамин: Начиная с MySQL 5.7.6 информационная_схема объединяется с производительной_схемой. Так что просто измените «information_schema» на «performance_schema» в запросе, чтобы он работал. Источник: dev.mysql.com/doc/refman/5.7/en/status-table.html
Ральф Болтон,

11

Что-то вроде этого? Использование SHOW VARIABLESи SHOW GLOBAL STATUS:

Выражение: innodb_buffer_pool_size / _ram
значение: % ОЗУ, используемое для InnoDB buffer_pool
Рекомендуемый диапазон: 60 ~ 80%

Выражение: Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests
Значение: запросы на чтение, которые должны были попасть на диск
Рекомендуемый диапазон: 0-2%
Что делать, если выходит за пределы диапазона: увеличить innodb_buffer_pool_size, если вам достаточно БАРАН.

Выражение: Innodb_pages_read / Innodb_buffer_pool_read_requests
Значение: запросы на чтение, которые должны были попасть на диск.
Рекомендуемый диапазон: 0-2%.
Что делать, если выходит за пределы диапазона: увеличить innodb_buffer_pool_size, если у вас достаточно оперативной памяти.

Выражение: Innodb_pages_written / Innodb_buffer_pool_write_requests
Значение: Запросы на запись, которые должны были попасть на диск.
Рекомендуемый диапазон: 0-15%.
Что делать, если вне диапазона: Проверьте innodb_buffer_pool_size.

Выражение: Innodb_buffer_pool_reads / Uptime
значение: читает.
Рекомендуемый диапазон: 0-100 / сек.
Что делать, если вне допустимого диапазона: увеличить innodb_buffer_pool_size?

Выражение: (Innodb_buffer_pool_reads + Innodb_buffer_pool_pages_flushed) / Uptime
Значение: InnoDB I / O
Рекомендуемый диапазон: 0-100 / сек.
Что делать, если вне допустимого диапазона: увеличить innodb_buffer_pool_size?

Выражение: Innodb_buffer_pool_pages_flushed / Uptime
Значение: пишет (мигает)
Рекомендуемый диапазон: 0-100 / сек.
Что делать, если вне допустимого диапазона: увеличить innodb_buffer_pool_size?

Выражение: Innodb_buffer_pool_wait_free / Uptime
Значение: Счетчик, когда в buffer_pool нет свободных страниц. То есть все страницы грязные.
Рекомендуемый диапазон: 0-1 / сек.
Что делать, если выходит за пределы диапазона: сначала убедитесь, что innodb_buffer_pool_size установлен разумно; если проблема не устранена, уменьшите innodb_max_dirty_pages_pct


Спасибо @Rick за хороший комментарий. Какое innodb_buffer_pool_sizeзначение указывает? Фактический размер или настроенный?
Джокер

1
@joker - innodb_buffer_pool_sizeуказывает максимальный размер. На типичном сервере «пул буферов» начинается с малого, но быстро увеличивается до максимального размера и остается там. Примечание: если это больше, чем ОЗУ (или даже близко), то это приводит к обмену, что ужасно для производительности.
Рик Джеймс

7

Ваш заголовок спрашивает о innodb_buffer_pool_size, но я подозреваю, что это не настоящая проблема. (Роландо прокомментировал, почему вы установили его достаточно большим, даже слишком большим.)

Я установил максимальное число соединений = 800, которые иногда насыщают и перемалывают сервер для остановки.

Это неясно. 800 пользователей в «спящем» режиме практически не влияют на работу системы. 800 активных потоков будет катастрофой. Сколько потоков "работает"?

Потоки блокируют друг друга? См. ПОКАЗАТЬ СТАТУС ДВИГАТЕЛЯ INNODB для получения информации о блокировках и т. Д.

Есть ли какие-либо запросы, отображаемые в медленном журнале? Давайте оптимизировать их.

Какую версию ты используешь? XtraDB (замена для InnoDB) лучше справляется с использованием нескольких ядер. 5.6.7 делает работу еще лучше.

innodb_buffer_pool_instances - измените это значение на 8 (при условии 20G buffer_pool); это немного сократит конкуренцию Mutex.

Вы связаны с вводом / выводом или с процессором? Решения радикально разные, в зависимости от вашего ответа.

SSD - было бы лучше, если бы все файлы журналов были на дисках не SSD.


6

Больше памяти всегда лучше, но, по моему опыту, в большинстве случаев размер пула буферов не должен соответствовать размеру ваших данных. Многие таблицы неактивны в большинстве случаев, например, таблицы резервных копий, поэтому размер пула буферов innodb должен соответствовать размеру активных данных.

Временной интервал, который вы указываете для активных страниц, влияет на производительность, но есть оптимальный момент, когда вы не получите такую ​​большую производительность при большем размере буфера. Вы можете оценить / рассчитать / измерить этоshow engine innodb status

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.