В следующем перечне дано описание некоторых аспектов использования памяти
сервером mysqld
. Там, где это возможно, приводятся имена серверных
переменных, относящихся к использованию памяти:
Буфер ключей (переменная
key_buffer_size
) используется совместно всеми потоками; другие буферы, используемые данным сервером, выделяются при необходимости (see Раздел 5.5.2, «Настройка параметров сервера»).Каждое соединение использует определенное пространство в памяти для конкретного потока: стек (по умолчанию 64Kб, переменная
thread_stack
), буфер соединения (переменнаяnet_buffer_length
) и буфер результата (переменнаяnet_buffer_length
). Буфер соединения и буфер результата при необходимости динамически расширяются вплоть доmax_allowed_packet
. При выполнении запроса также выделяется память для копии строки данного текущего запроса.-
Все потоки совместно используют одну и туже базовую память.
Только сжатые таблицы типа
ISAM/MyISAM
имеют распределенную память. Это объясняется тем, что 4 Гб памяти (адресуемой в рамках 32-битной разрядности) мало для достаточно больших таблиц. Когда системы с 64-разрядными адресным пространством получат более широкое распространение, мы сможем добавить в сервер общую поддержку для распределения памяти. Каждый запрос, выполняющий последовательный просмотр таблицы, размещается в буфере чтения (переменная
record_buffer
).При чтении строк в "случайном" порядке (например, после сортировки) выделяется буфер "случайного чтения", чтобы избежать поиска по диску (переменная
record_rnd_buffer
).Все объединения выполняются за одну операцию, и большинство объединений может производиться даже без временных таблиц. Большинство временных таблиц располагаются в оперативной памяти (в динамически выделяемой области
HEAP
). Временные таблицы с записями большой длины (вычисляемой как сумма длин всех столбцов) или таблицы, содержащие столбцыBLOB
, хранятся на диске. В версиях MySQL до 3.23.2 существует проблема, заключающаяся в том, что если таблицыHEAP
в динамически выделяемой области превышают размерtmp_table_size
, то возникает ошибкаThe table tbl_name is full
. В более новых версиях эта проблема при необходимости решается путем автоматического преобразования хранящихся в оперативной памятиHEAP
-таблиц в таблицыMyISAM
, расположенные на диске. Чтобы обойти эту проблему, можно увеличить размер временных таблиц установкой опцииtmp_table_size
вmysqld
или установкой SQL-опцииSQL_BIG_TABLES
в клиентской программе (see Раздел 5.5.6, «Синтаксис командыSET
»). В версии MySQL 3.20 максимальный размер временной таблицы был равенrecord_buffer*16
, так что при использовании данной версии необходимо увеличить значениеrecord_buffer
. Можно также запуститьmysqld
с опцией--big-tables
- для того, чтобы всегда хранить временные таблицы на диске. Однако это будет влиять на скорость многих сложных запросов.Большинство запросов, выполняющих сортировку, размещаются в буфере сортировки и в 0-2 временных файлах, в зависимости от размера результирующего набора данных (see Раздел A.4.4, «Где MySQL хранит временные файлы»).
Почти все операции, связанные с анализом и вычислениями, выполняются в пространстве локальной памяти. Для небольших задач не требуется никаких дополнительных затрат памяти и удается избежать обычно медленных процессов выделения и освобождения памяти. Память выделяется только для непредвиденно больших строк (это делается с помощью функций
malloc()
иfree()
).Каждый файл индексов и файл данных открываются сразу для каждого параллельно работающего потока. Для каждого параллельного потока выделяется место в памяти для структуры таблицы, структур столбцов для каждого столбца и буфер размером 3 * n (где n представляет максимальную длину строки без учета столбцов
BLOB
). Для столбцаBLOB
используется от 5 до 8 байтов плюс длина данныхBLOB
. Обработчики таблицISAM/MyISAM
будут использовать один дополнительный буфер строки для внутреннего представления.Для каждой таблицы, имеющей столбцы
BLOB
, буфер динамически увеличивается при чтении больших величинBLOB
. При просмотре таблицы выделяется буфер с размером, равным наибольшей величинеBLOB
.Обработчики всех находящихся в употреблении таблиц хранятся в кэше и обрабатываются в порядке их поступления (режим FIFO). Обычно этот кэш содержит 64 элемента. Если данная таблица была использована двумя работающими потоками в одно и то же время, то кэш содержит два элемента для такой таблицы (see Раздел 5.4.7, «Открытие и закрытие таблиц в MySQL»).
Команда
mysqladmin flush-tables
закрывает все неиспользуемые таблицы и отмечает все используемые таблицы, которые необходимо закрыть после окончания выполнения текущего потока. Такой алгоритм позволяет эффективно освобождать большое количество используемой памяти.
Программа ps
и другие программы контроля состояния системы могут сообщать,
что mysqld
использует слишком много памяти. Это может быть вызвано
расположением стеков памяти потоков по различным адресам в памяти.
Например, версия программы ps для Solaris интерпретирует неиспользуемую
память между стеками как используемую. Это можно проверить путем
выполнения допустимой перестановки с помощью swap -s
. Мы тестировали
mysqld
при помощи коммерческих детекторов утечки памяти, так что никаких
потерь памяти быть не должно.