Наскільки великим повинен бути mysql innodb_buffer_pool_size?


170

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

Я бачив пропозиції, що innodb_buffer_pool_size повинен становити до% 80 від загальної пам'яті. З іншого боку, я отримую це попередження від настройки сценарію настройки-праймера:

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). Я впевнений, що це буде набагато менше, ніж 20000 млн, які ви зарезервували зараз. Заощадження в оперативній пам’яті можна використовувати для налаштування інших подібних речей

КАВАТИ №1

Це дуже важливо зауважити: інколи InnoDB може вимагати додаткових 10% над значенням для innodb_buffer_pool_size . Ось що говорить Документація MySQL щодо цього:

Чим більше ви встановите це значення, тим менше вводу / виводу диска потрібно для доступу до даних у таблицях. На спеціальному сервері баз даних ви можете встановити це до 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 Гб. Прочитавши вашу відповідь / статтю, швидкість посилань піднялася до 2x
fat_mike

4
@Benjamin: Станом на MySQL 5.7.6 інформація_схема об'єднується у performance_schema. Тому просто змініть "information_schema" на "performance_schema" у запиті, щоб він працював. Джерело: dev.mysql.com/doc/refman/5.7/uk/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 активних ниток було б лихом. Скільки ниток "працює"?

Чи блокують нитки один одного? Дивіться ШОУ ДЛЯ ДВИГАТЕЛЯ ІННОДБОВОГО СТАТУСУ за деякими підказками про тупикові місця тощо

Чи з’являються запити у повільному журналі? Давайте оптимізуємо їх.

Яку версію ви використовуєте? XtraDB (заміна, що випадає на InnoDB) робить кращу роботу з використанням декількох ядер. 5.6.7 робить ще кращу роботу.

innodb_buffer_pool_instance - змініть це на 8 (припустимо, 20G buffer_pool); вона трохи зменшиться за твердженням Мутекса.

Ви пов'язані вводу / виводу або пов'язані з процесором? Рішення кардинально відрізняються, залежно від вашої відповіді.

SSD - Це може бути краще, якби всі файли журналу знаходилися на дисках, що не є SSD.


6

Більше пам’яті завжди краще, але, на мій досвід, більшість разів розмір пулу буфера не повинен відповідати вашому розміру даних. Багато таблиць в більшості випадків неактивні, як таблиці резервного копіювання, що лежать навколо, тому розмір пулу innodb буфера повинен скоріше відповідати вашому сприятливому розміру даних.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.