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

Почему наша таблица MySQL открывает такие большие, а попадание в кеш так низко?

Мы видим странную статистику по количеству открытий столов. Я добавил дамп mysqltuner ниже.

В нем говорится, что мы открыли 94 000 столов за последние 24 часа. Но всего существует всего 15 000 таблиц, и мы знаем, что на этом конкретном репликанте с ведомым устройством чтения осуществляется доступ только к 100 таблицам.

Кроме того, в нем говорится, что мы кэшируем только 2k из 94k.

Как мне понять эти цифры? И как исправить проблему с кешированием - конечно, мы можем «увеличить кеш таблицы», но это не похоже на основную проблему.

-------- General Statistics --------------------------------------------------
[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.1.41-3ubuntu12.9-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -------------------------------------------
[--] Status: -Archive -BDB -Federated +InnoDB -ISAM -NDBCluster 
[--] Data in MyISAM tables: 4G (Tables: 14960)
[--] Data in InnoDB tables: 225M (Tables: 570)
[!!] Total fragmented tables: 2115

-------- Performance Metrics -------------------------------------------------
[--] Up for: 2h 13m 36s (647K q [80.798 qps], 28K conn, TX: 247B, RX: 542M)
[--] Reads / Writes: 63% / 37%
[--] Total buffers: 2.5G global + 2.7M per thread (1000 max threads)
[OK] Maximum possible memory usage: 5.2G (66% of installed RAM)
[OK] Slow queries: 0% (783/647K)
[OK] Highest usage of available connections: 5% (57/1000)
[OK] Key buffer size / total MyISAM indexes: 1.0G/1.4G
[OK] Key buffer hit rate: 100.0% (763M cached / 74K reads)
[OK] Query cache efficiency: 55.5% (335K cached / 604K selects)
[OK] Query cache prunes per day: 0
[OK] Sorts requiring temporary tables: 0% (312 temp sorts / 113K sorts)
[!!] Temporary tables created on disk: 47% (59K on disk / 124K total)
[OK] Thread cache hit rate: 99% (63 created / 28K connections)
[!!] Table cache hit rate: 2% (2K open / 94K opened)
[OK] Open file limit used: 75% (3K/5K)
[OK] Table locks acquired immediately: 99% (577K immediate / 583K locks)
[!!] Connections aborted: 45%
[OK] InnoDB data size / buffer pool: 225.3M/256.0M

-------- Recommendations -----------------------------------------------------
General recommendations:
    Run OPTIMIZE TABLE to defragment tables for better performance
    MySQL started within last 24 hours - recommendations may be inaccurate
    Temporary table size is already large - reduce result set size
    Reduce your SELECT DISTINCT queries without LIMIT clauses
    Increase table_cache gradually to avoid file descriptor limits
    Your applications are not closing MySQL connections properly
Variables to adjust:
    table_cache (> 2048)

Видеть Как MySQL открывает / закрывает таблицы в официальном руководстве для довольно хорошего описания кеша таблиц и того, как он используется, а также некоторых полезных комментариев. Каждая таблица, используемая в запросе, может иметь несколько дескрипторов для каждого соединения, что означает, что если у вас высокий уровень параллелизма запросов и вы используете запросы, содержащие много таблиц, для каждой таблицы могут потребоваться десятки дескрипторов.

Полезная вещь, которую вы можете сделать, - это использовать какую-либо форму мониторинга для проверки значений open_table / opens_tables каждую минуту или около того и посмотреть, как они себя ведут. В моем случае легко увидеть, что внезапные пики трафика, вероятно, являются причиной значительного увеличения open_tables.

А также есть этот ТАК вопрос который очень похож на ваш.

lwdba @ localhost (схема_информации БД) :: показать такие переменные, как 'query%';
+ ------------------------------ + ---------- +
| Имя_переменной | Значение |
+ ------------------------------ + ---------- +
| query_alloc_block_size | 8192 |
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 67108864 |
| query_cache_type | ВКЛ |
| query_cache_wlock_invalidate | ВЫКЛ |
| query_prealloc_size | 8192 |
+ ------------------------------ + ---------- +

На этом дисплее query_cache_size (глобальная переменная) 64M. В query_cache_limit составляет 1M.

Это означает, что у меня может быть до 64 кэшированных запросов, максимальный набор данных которых составляет 1 Мбайт или меньше, или 128 запросов, кэшированных с наборами данных 500 КБ, или любая другая комбинация, которая может составлять до 64 Мбайт.

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