MySQL table_cache и Opened_tables

14

Я видел, как люди используют сравнение Open_tables и Opened_tables, чтобы оценить, слишком ли мала таблица_cache в MySQL. Тем не менее, я считаю, что Opened_tables накапливается в течение времени безотказной работы, так что это недопустимое сравнение Единственное предостережение в том, что, возможно, Opened_tables сталкивается только с промахами - хотя даже в этом случае, если количество таблиц, открываемых за секунду, все еще невелико, его рост, вероятно, не составляет проблемы.

Если сравнение Open_tables с Opened_tables недопустимо, есть ли другой способ получить измеренные данные для этого?

Это на MySQL 5.0, но различия между версиями тоже приветствуются.

Сэм Брайтман
источник
Мне нравится этот вопрос, потому что это вопрос, заставляющий задуматься. Это дает +1 за напоминание разработчикам MySQL более полно использовать переменные состояния для измерения работоспособности DB Server.
RolandoMySQLDBA

Ответы:

7

Основная причина наличия большого table_cache заключается в том, что мьютекс LOCK_open не горячий. MySQL до 5.5 имеет много споров, когда вы пытаетесь открыть / закрыть таблицы, поэтому вы хотите максимально ограничить это, то есть иметь большой кеш таблиц.

Таким образом, вас не волнует какое-либо конкретное соотношение попаданий и промахов (на самом деле вы должны игнорировать соотношения вообще - этот пост в блоге объясняет почему ). Что вас беспокоит, так это частота пропусков , потому что чем больше раз это происходит в секунду, тем выше вероятность того, что у вас возникнет конфликт (один поток должен ждать, пока другой поток снимет блокировку).

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

Примечание: я очень не рекомендую сравнивать с временем безотказной работы.

Морган Токер
источник
5

Сначала давайте рассмотрим эти переменные состояния:

Открытые таблицы : количество открытых таблиц.

Opened_tables : количество открытых таблиц. Если Opened_tables большой, ваше значение table_open_cache, вероятно, слишком мало.

Удивительно, но ответ на ваш вопрос лежит в самом вопросе.

Две переменные будут иметь больше смысла, только если вы добавите еще одну переменную состояния в смесь: Uptime (или статус Uptime_since_flush для свежих средних после FLUSH STATUS ).

Вы должны сравнивать Open_tables agsinst (Opened_tables / Uptime) . Если Open_tables поднимается выше (Opened_tables / Uptime) , теперь у вас есть повод для беспокойства и следует следить за такими вещами, как:

ОБНОВЛЕНИЕ 2011-08-31 12:18 ПО ВОСТОЧНОМУ ВРЕМЕНИ

Обратите внимание, почему я также предложил использовать Uptime_since_flush_status вместо Uptime, чтобы получить фиксированный паттерн роста Opened_tables за определенный период.

Например, если вы запускаете FLUSH STATUS;каждый понедельник в полночь, вы можете сгенерировать OpenTableFactor:

SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM
(SELECT variable_value Uptime FROM information_schema.global_status
WHERE variable_name = 'Uptime_since_flush_status') up,
(SELECT variable_value Open_tables FROM information_schema.global_status
WHERE variable_name = 'Open_tables') opn,
(SELECT IF(variable_value=0,1,variable_value) Opened_tables
FROM information_schema.global_status
WHERE variable_name = 'Opened_tables') opnd;

Этот коэффициент открытых таблиц представляет собой число, которое представляет количество открытых таблиц в любой данный момент по сравнению со средним числом открытых таблиц за указанный период. Для FLUSH HOSTS;каждой недели / дня / хоста это среднее значение соответствует неделям / дням / часам.

Вот пример одного из клиентов моего работодателя:

mysql> SELECT *, (Open_tables * Uptime / Opened_Tables) OpenTableFactor FROM     (SELECT variable_value Uptime FROM information_sc    hema.global_status     WHERE variable_name = 'Uptime_since_flush_status') up,     (SELECT variable_value Open_tables FROM informat    ion_schema.global_status     WHERE variable_name = 'Open_tables') opn,     (SELECT IF(variable_value=0,1,variable_value) Opened_ta    bles     FROM information_schema.global_status     WHERE variable_name = 'Opened_tables') opnd;
+----------+-------------+---------------+-------------------+
| Uptime   | Open_tables | Opened_tables | OpenTableFactor   |
+----------+-------------+---------------+-------------------+
| 14385123 | 16326       | 30429078      | 7717.996519579068 |
+----------+-------------+---------------+-------------------+
1 row in set (0.00 sec)

Этот клиент обычно поддерживает около 7745 OpenTableFactor на макс. Если OpenTableFactor внезапно падает (даже если немного), это может указывать на более низкий уровень трафика, прерванные соединения и т. Д. Если OpenTableFactor никогда не изменяется (даже если немного), он может предоставить вам возможность изменить эти настройки:

После настройки OpenTableFactor может постоянно меняться или достигать другого потолка или плато. Таким образом, использование различных единиц в переменных состояния становится жизненно важным для этого типа настройки.

ОБНОВЛЕНИЕ 2011-08-31 12:42 ПО ВОСТОЧНОМУ ВРЕМЕНИ

SQL-запрос, который я выполнил для OpenTableFactor, не работает для MySQL 5.0 и обратно. Если вы используете MySQL Administrator или MONyog , вы можете настроить график, используя формулу в запросе и мониторе. MONyog собирает историю, используя SQLLite для последующего исторического построения графиков. Это можно сделать для любой версии MySQL.

RolandoMySQLDBA
источник
Несколько хороших предложений, но я не думаю, что вы хотите сравнивать две вещи с разными единицами больше, чем сравнивать совокупное значение с текущим. И вопрос о том, что это всего лишь мера промахов, остается.
Сэм Брайтман
3

От одного из комментариев пользователя на странице документации table_cache :

Opened_tables - это переменная состояния, которая ведет подсчет количества дополнительных файловых дескрипторов, которые были выделены для открытия таблиц, когда доступные файловые дескрипторы в table_cache были исчерпаны. ...

Это означает, что оно увеличивается, когда вы перебираете свое table_cacheзначение. Так как я обычно проверить это сравнить opened_tablesс uptime, но ключ здесь , чтобы принять его в течение заданного интервала (один раз в минуту в течение десяти минут, например). Если он увеличивается, это может быть признаком того, что вам нужно увеличить свой table_cache.

Несколько предостережений, чтобы упомянуть:

  • Другой комментарий в этой документации выше: «Переменная состояния« Opened_tables »также будет увеличиваться на 2 каждый раз, когда вы создаете временную таблицу». Так что если ваши запросы требуют много временных таблиц, это может быть причиной быстрого увеличения opened_tables. Вы можете увидеть использование вашей временной таблицы, используя следующий запрос:

    SHOW GLOBAL STATUS LIKE '%tmp%';

  • Не увеличивайте table_cache слишком высоко

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

Дерек Дауни
источник