15.3 Двигатель хранения MEMORY
Двигатель хранения MEMORY (ранее известный как HEAP) создаёт таблицы специального назначения со содержимым, хранящимся в оперативной памяти. Поскольку данные уязвимы к сбоям, проблемам с оборудованием или отключению питания, используйте эти таблицы только в качестве временных рабочих областей или только для чтения кэшей данных, извлечённых из других таблиц.
Таблица 15.4 Возможности двигателя хранения MEMORY
| Функция | Поддержка |
|---|---|
| Индексы B-дерева | Да |
| Резервное копирование/восстановление по состоянию на определённый момент времени (Реализовано в сервере, а не в движке хранения.) | Да |
| Поддержка кластерной базы данных | Нет |
| Кластеризованные индексы | Нет |
| Сжатые данные | Нет |
| Кэши данных | Н/Д |
| Зашифрованные данные | Да (Реализовано в сервере с помощью функций шифрования.) |
| Поддержка внешних ключей | Нет |
| Индексы полнотекстового поиска | Нет |
| Поддержка геопространственных типов данных | Нет |
| Поддержка геопространственной индексации | Нет |
| Индексы хеширования | Да |
| Кэши индексов | Н/Д |
| Степень блокировки | Таблица |
| MVCC | Нет |
| Поддержка репликации (Реализовано в сервере, а не в движке хранения.) | Ограниченная (См. обсуждение позже в этом разделе.) |
| Ограничения по хранилищу | ОЗУ |
| Индексы T-дерева | Нет |
| Транзакции | Нет |
| Обновление статистики словаря данных | Да |
Когда использовать MEMORY или NDB Cluster
Разработчики, планирующие использовать двигатель хранения MEMORY для важных, высокодоступных или часто обновляемых данных, должны рассмотреть, является ли NDB Cluster лучшим выбором. Типичный сценарий использования двигателя MEMORY включает следующие характеристики:
Операции с временными, некритическими данными, такими как управление сессиями или кэшированием. При остановке или перезапуске сервера MySQL данные в таблицах
MEMORYтеряются.Хранение в оперативной памяти для быстрого доступа и низкой задержки. Объём данных может поместиться полностью в оперативной памяти, не вызывая подкачки страниц виртуальной памяти операционной системой.
Обработка данных в основном только для чтения (ограниченные обновления).
NDB Cluster предлагает те же функции, что и двигатель MEMORY, но с более высокой производительностью и дополнительными функциями, недоступными с MEMORY:
Блокировка на уровне строк и многопоточная работа для снижения конкуренции между клиентами.
Масштабируемость даже при смешанных операциях, включающих записи.
Дополнительная возможность сохранения данных на диске для обеспечения надёжности.
Архитектура shared-nothing и многохостовая работа без единой точки отказа, обеспечивающая доступность 99,999 %.
Автоматическое распределение данных по узлам; разработчикам приложений не нужно создавать собственные решения фрагментации или разбиения.
Поддержка типов данных переменной длины (включая
BLOBиTEXT), которые не поддерживаютсяMEMORY.
Характеристики производительности
Производительность MEMORY ограничена конкуренцией, возникающей из-за однопоточной обработки и накладных расходов на блокировку таблиц при обработке обновлений. Это ограничивает масштабируемость при увеличении нагрузки, особенно для смешанных операций, включающих записи.
Несмотря на обработку в оперативной памяти для таблиц MEMORY, они не обязательно быстрее, чем таблицы InnoDB на загруженном сервере для запросов общего назначения или при нагрузке чтения/записи. В частности, блокировка таблиц, необходимая для выполнения обновлений, может замедлить одновременное использование таблиц MEMORY из нескольких сессий.
В зависимости от типа запросов, выполняемых к таблице MEMORY, вы можете создавать индексы в качестве структуры данных по умолчанию типа хэш (для поиска отдельных значений на основе уникального ключа) или структуры данных B-дерева общего назначения (для всех типов запросов, включающих операторы равенства, неравенства или диапазона, такие как меньше или больше). В следующих разделах показан синтаксис для создания обоих типов индексов. Распространённая проблема производительности — использование индексов хэш по умолчанию в рабочих нагрузках, где индексы B-дерева более эффективны.
Характеристики таблиц MEMORY
Двигатель хранения MEMORY связывает каждую таблицу с одним файлом на диске, который хранит определение таблицы (а не данные). Имя файла начинается с имени таблицы и имеет расширение .frm.
Таблицы MEMORY имеют следующие характеристики:
Память для таблиц
MEMORYвыделяется небольшими блоками. Таблицы используют 100% динамическое хеширование для вставок. Не требуется область переполнения или дополнительное пространство для ключей. Не требуется дополнительного пространства для свободных списков. Удалённые строки помещаются в связанный список и повторно используются при вставке новых данных в таблицу. ТаблицыMEMORYтакже не имеют проблем, обычно связанных с удалениями и вставками в хешированных таблицах.Таблицы
MEMORYиспользуют формат хранения строк фиксированной длины. Типы переменной длины, такие какVARCHAR, хранятся с фиксированной длиной.MEMORYвключает поддержку столбцовAUTO_INCREMENT.Таблицы
TEMPORARYMEMORYразделяются между всеми клиентами, как и любая другая таблица, не являющаясяTEMPORARY.
Операции DDL для таблиц MEMORY
Для создания таблицы MEMORY укажите предложение ENGINE=MEMORY в операторе CREATE TABLE.
CREATE TABLE t (i INT) ENGINE = MEMORY;
Как следует из названия движка, таблицы MEMORY хранятся в оперативной памяти. По умолчанию они используют индексы хэширования, что делает их очень быстрыми для поиска по одному значению и очень полезными для создания временных таблиц. Однако при завершении работы сервера все строки, хранящиеся в таблицах MEMORY, теряются. Сами таблицы продолжают существовать, так как их определения хранятся в файлах .frm на диске, но они пусты при перезапуске сервера.
В этом примере показано, как создать, использовать и удалить таблицу MEMORY:
mysql> CREATE TABLE test ENGINE=MEMORY
SELECT ip,SUM(downloads) AS down
FROM log_table GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;
Максимальный размер таблиц MEMORY ограничен переменной системы max_heap_table_size, которая имеет значение по умолчанию 16 МБ. Для применения различных ограничений размера для таблиц MEMORY измените значение этой переменной. Значение, применяемое к CREATE TABLE, или последующему ALTER TABLE или TRUNCATE TABLE, используется на протяжении всего срока существования таблицы. Перезапуск сервера также устанавливает максимальный размер существующих таблиц MEMORY на глобальное значение max_heap_table_size.
Индексы
Движок хранения MEMORY поддерживает индексы HASH и BTREE. Вы можете указать тот или другой для данного индекса, добавив предложение USING, как показано здесь:
CREATE TABLE lookup
(id INT, INDEX USING HASH (id))
ENGINE = MEMORY;
CREATE TABLE lookup
(id INT, INDEX USING BTREE (id))
ENGINE = MEMORY;
Общие характеристики индексов B-дерева и хэширования см. в разделе 8.3.1 «Как MySQL использует индексы».
Таблицы MEMORY могут иметь до 64 индексов на таблицу, 16 столбцов на индекс и максимальную длину ключа 3072 байта.
Если индекс хэширования таблицы MEMORY имеет высокую степень дублирования ключей (многие записи индекса содержат одно и то же значение), обновления таблицы, влияющие на значения ключей и все удаления, будут значительно медленнее. Степень этого замедления пропорциональна степени дублирования (или обратно пропорциональна степени мощности индекса). Чтобы избежать этой проблемы, вы можете использовать индекс BTREE.
Таблицы MEMORY могут иметь не уникальные ключи. (Это редкая функция для реализаций индексов хэширования.)
Столбцы, которые индексируются, могут содержать значения NULL.
Пользовательские и временные таблицы
Содержимое таблиц MEMORY хранится в оперативной памяти, что является свойством, которое таблицы MEMORY разделяют с внутренними временными таблицами, которые сервер создает на лету во время обработки запросов. Однако два типа таблиц отличаются тем, что таблицы MEMORY не подвержены преобразованию хранения, в то время как внутренние временные таблицы подвержены:
Если внутренняя временная таблица становится слишком большой, сервер автоматически преобразует её в хранилище на диске, как описано в разделе 8.4.4 «Использование внутренних временных таблиц в MySQL».
Пользовательские таблицы
MEMORYникогда не преобразуются в таблицы на диске.
Загрузка данных
Чтобы заполнить таблицу MEMORY при запуске сервера MySQL, можно использовать переменную системы init_file. Например, вы можете поместить операторы, такие как INSERT INTO ...
SELECT или LOAD DATA в файл для загрузки таблицы из постоянного источника данных и использовать init_file для именования файла. См. раздел 5.1.7 «Переменные системы сервера» и раздел 13.2.6 «Оператор LOAD DATA».
Таблицы MEMORY и репликация
При завершении и перезапуске сервера репликации, использующего таблицы MEMORY, они становятся пустыми. Чтобы реплицировать этот эффект на репликах, в первый раз, когда источник использует заданную таблицу MEMORY после запуска, он регистрирует событие, которое уведомляет реплики, что таблица должна быть опустошена путем записи оператора DELETE или (начиная с MySQL 5.7.32) TRUNCATE
TABLE для этой таблицы в двоичный журнал. При завершении и перезапуске сервера реплики его таблицы MEMORY также становятся пустыми, и он записывает оператор DELETE или (начиная с MySQL 5.7.32) TRUNCATE TABLE в свой двоичный журнал, который передаётся любым последующим репликам.
При использовании таблиц MEMORY в топологии репликации в некоторых ситуациях таблица на источнике и таблица на реплике могут отличаться. Для получения информации о том, как обрабатывать каждую из этих ситуаций, чтобы предотвратить устаревшие чтения или ошибки, см. раздел 16.4.1.20 «Репликация и таблицы MEMORY».
Управление использованием памяти
Серверу требуется достаточное количество памяти для поддержания всех таблиц MEMORY, используемых одновременно.
Память не возвращается, если вы удаляете отдельные строки из таблицы MEMORY. Память возвращается только при полном удалении таблицы. Память, которая ранее использовалась для удалённых строк, повторно используется для новых строк в той же таблице.
Чтобы освободить всю память, используемую таблицей MEMORY, когда её содержимое больше не требуется, выполните DELETE или TRUNCATE TABLE для удаления всех строк или удалите таблицу полностью с помощью DROP
TABLE. Чтобы освободить память, используемую удаленными строками, используйте ALTER TABLE ENGINE=MEMORY, чтобы принудительно перестроить таблицу.
Необходимая память для одной строки в таблице MEMORY рассчитывается по следующему выражению:
SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4)
+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))
ALIGN() представляет собой коэффициент округления, чтобы сделать длину строки точным кратным размеру указателя char. sizeof(char*) составляет 4 на 32-битных машинах и 8 на 64-битных машинах.
Как упоминалось ранее, переменная системы max_heap_table_size устанавливает предел максимального размера таблиц MEMORY. Чтобы контролировать максимальный размер отдельных таблиц, установите сеансовое значение этой переменной перед созданием каждой таблицы. (Не изменяйте глобальное значение max_heap_table_size, если вы не хотите, чтобы это значение использовалось для таблиц MEMORY, создаваемых всеми клиентами.) В следующем примере создаются две таблицы MEMORY с максимальным размером 1 МБ и 2 МБ соответственно:
mysql> SET max_heap_table_size = 1024*1024;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.01 sec)
mysql> SET max_heap_table_size = 1024*1024*2;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY;
Query OK, 0 rows affected (0.00 sec)
Обе таблицы возвращаются к глобальному значению сервера max_heap_table_size при перезапуске сервера.
Вы также можете указать параметр таблицы MAX_ROWS в операторах CREATE TABLE для таблиц MEMORY, чтобы дать подсказку о предполагаемом количестве строк, которые будут в них храниться. Это не позволяет таблице увеличиться сверх значения max_heap_table_size, которое по-прежнему действует как ограничение максимального размера таблицы. Для максимальной гибкости использования таблиц MAX_ROWS установите max_heap_table_size как минимум так же высоко, как значение, до которого вы хотите, чтобы каждая таблица MEMORY могла расти.
Дополнительные ресурсы
Форум, посвященный движку хранения MEMORY, доступен по адресу https://forums.mysql.com/list.php?92.
© 2025 Oracle
Licensed under the GPLv2 License.