Spec-Zone.ru › MySQL 8.4

18.3 Двигатель хранения MEMORY

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

Таблица 18.4 Возможности двигателя хранения MEMORY

Таблица 18.4 Возможности двигателя хранения MEMORY
Функция Поддержка
Индексы B-дерева Да
Резервное копирование/восстановление в заданный момент времени (Реализовано в сервере, а не в движке хранения.) Да
Поддержка кластерной базы данных Нет
Кластеризованные индексы Нет
Сжатые данные Нет
Кэши данных Нет данных
Зашифрованные данные Да (Реализовано в сервере с помощью функций шифрования.)
Поддержка внешних ключей Нет
Индексы полнотекстового поиска Нет
Поддержка геопространственных типов данных Нет
Поддержка геопространственной индексации Нет
Индексы хешей Да
Кэши индексов Нет данных
Грань блокировки Таблица
MVCC Нет
Поддержка репликации (Реализовано в сервере, а не в движке хранения.) Ограниченная (См. обсуждение позже в этом разделе.)
Пределы хранения ОЗУ
Индексы T-дерева Нет
Транзакции Нет
Обновление статистики для словаря данных Да

  • Когда использовать MEMORY или NDB Cluster

  • Разбиение

  • Характеристики производительности

  • Особенности таблиц MEMORY

  • Операции DDL для таблиц MEMORY

  • Индексы

  • Пользовательские и временные таблицы

  • Загрузка данных

  • Таблицы MEMORY и репликация

  • Управление использованием памяти

  • Дополнительные ресурсы

Когда использовать MEMORY или NDB Cluster

Разработчики, планирующие использовать движок хранения MEMORY для важных, высокодоступных или часто обновляемых данных, должны рассмотреть, подходит ли NDB Cluster для этого случая. Типичное использование движка MEMORY включает следующие характеристики:

  • Операции, связанные с временными, некритическими данными, такими как управление сессиями или кэширование. При остановке или перезапуске MySQL-сервера данные в таблицах MEMORY теряются.

  • Хранение в оперативной памяти для быстрого доступа и низкой задержки. Объем данных может полностью поместиться в оперативную память, не вызывая обмена виртуальной памяти.

  • Читать-только или преимущественно читательный режим доступа к данным (ограниченные обновления).

NDB Cluster предлагает те же функции, что и движок MEMORY, но с большей производительностью и дополнительными функциями, недоступными в MEMORY:

  • Блокировка на уровне строк и многопоточность для снижения конкуренции между клиентами.

  • Масштабируемость даже при смешанных операциях, включающих записи.

  • Дополнительное хранение на диске для обеспечения сохранности данных.

  • Архитектура shared-nothing и многохостовая работа без единой точки отказа, обеспечивающая доступность 99,999%.

  • Автоматическое распределение данных по узлам; разработчикам приложений не нужно разрабатывать собственные решения для фрагментации или разбиения.

  • Поддержка типов данных переменной длины (включая BLOB и TEXT), не поддерживаемые MEMORY.

Разбиение

Таблицы MEMORY не могут быть разбиты.

Характеристики производительности

Производительность MEMORY ограничена конкуренцией, возникающей из-за однопоточной обработки и накладных расходов на блокировку таблиц при обработке обновлений. Это ограничивает масштабируемость при увеличении нагрузки, особенно для смешанных операций, включающих записи.

Несмотря на обработку в оперативной памяти для таблиц MEMORY, они не обязательно быстрее, чем таблицы InnoDB на загруженном сервере, при общем запросе или при работе с чтением/записью. В частности, блокировка таблиц при выполнении обновлений может замедлить одновременное использование таблиц MEMORY из нескольких сеансов.

В зависимости от типа запросов, выполняемых к таблице MEMORY, вы можете создать индексы как в виде стандартной структуры данных хеш (для поиска отдельных значений на основе уникального ключа), так и в виде универсальной структуры B-дерева (для всех типов запросов, включающих операторы равенства, неравенства или диапазона, такие как меньше или больше). В следующих разделах показан синтаксис создания обоих типов индексов. Распространённой проблемой производительности является использование стандартных индексов хеш в тех сценариях, где B-деревья более эффективны.

Особенности таблиц MEMORY

Движок хранения MEMORY не создает никаких файлов на диске. Определение таблицы хранится в словаре данных MySQL.

Таблицы MEMORY имеют следующие особенности:

  • Память для таблиц MEMORY выделяется небольшими блоками. Таблицы используют 100% динамическое хеширование для вставок. Не требуется область переполнения или дополнительное пространство для ключей. Не требуется дополнительное пространство для списков свободных мест. Удаленные строки помещаются в связанный список и повторно используются при вставке новых данных в таблицу. Таблицы MEMORY также не имеют проблем, обычно связанных с удалением и последующими вставками в хеш-таблицы.

  • Таблицы MEMORY используют формат хранения строк фиксированной длины. Типы переменной длины, такие как VARCHAR, хранятся с использованием фиксированной длины.

  • Таблицы MEMORY не могут содержать столбцы BLOB или TEXT.

  • MEMORY включает поддержку столбцов AUTO_INCREMENT.

  • Не-TEMPORARY MEMORY таблицы разделяются между всеми клиентами, как и любые другие таблицы, не являющиеся TEMPORARY.

Операции DDL для таблиц MEMORY

Для создания таблицы MEMORY укажите предложение ENGINE=MEMORY в операторе CREATE TABLE.

CREATE TABLE t (i INT) ENGINE = MEMORY;

Как следует из названия движка, таблицы MEMORY хранятся в памяти. По умолчанию они используют хэш-индексы, что делает их очень быстрыми для поиска по одному значению и очень полезными для создания временных таблиц. Однако при остановке сервера все строки, хранящиеся в таблицах MEMORY, будут утеряны. Сами таблицы продолжают существовать, потому что их определения хранятся в словаре данных MySQL, но они пустые при перезапуске сервера.

Этот пример показывает, как можно создать, использовать и удалить таблицу 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-деревянных и хэш-индексов см. в разделе 10.3.1, «Как MySQL использует индексы».

Таблицы MEMORY могут иметь до 64 индексов на таблицу, 16 столбцов на индекс и максимальную длину ключа 3072 байта.

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

Таблицы MEMORY могут иметь не уникальные ключи. (Это редкая функция для реализации хэш-индексов.)

Столбцы, которые индексируются, могут содержать NULL значения.

Пользовательские и временные таблицы

Содержимое таблиц MEMORY хранится в памяти, что является свойством, которое разделяют таблицы MEMORY с внутренними временными таблицами, которые сервер создает на лету при обработке запросов. Однако эти типы таблиц отличаются тем, что таблицы MEMORY не подвержены преобразованию хранилища, в то время как внутренние временные таблицы — подвержены:

  • Если внутренняя временная таблица становится слишком большой, сервер автоматически преобразует ее в хранение на диске, как описано в разделе 10.4.4, «Использование внутренних временных таблиц в MySQL».

  • Пользовательские таблицы MEMORY никогда не преобразуются в таблицы на диске.

Загрузка данных

Для заполнения таблицы MEMORY при запуске сервера MySQL можно использовать системную переменную init_file. Например, вы можете поместить операторы, такие как INSERT INTO ... SELECT или LOAD DATA в файл, чтобы загрузить таблицу из постоянного источника данных, и использовать init_file для указания имени файла. См. раздел 7.1.8, «Системные переменные сервера» и раздел 15.2.9, «Оператор LOAD DATA».

Таблицы MEMORY и репликация

Когда реплицирующий сервер останавливается и перезапускается, его таблицы MEMORY становятся пустыми. Чтобы повторить этот эффект для реплик, в первый раз, когда источник использует заданную таблицу MEMORY после запуска, он регистрирует событие, которое уведомляет реплики о том, что таблица должна быть очищена, записывая оператор TRUNCATE TABLE для этой таблицы в двоичный журнал. Когда реплицирующий сервер останавливается и перезапускается, его таблицы MEMORY также становятся пустыми, и он записывает оператор TRUNCATE TABLE в свой собственный двоичный журнал, который передается любым последующим репликам.

При использовании таблиц MEMORY в топологии репликации в некоторых ситуациях таблица на источнике и таблица на реплике могут отличаться. Сведения о том, как обрабатывать каждую из этих ситуаций, чтобы предотвратить устаревшие чтения или ошибки, см. в разделе 19.5.1.21, «Репликация и таблицы 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.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/memory-storage-engine.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API