Сервер Firebird и оперативная память

Материал из GedeminWiki
Перейти к: навигация, поиск

У системных администраторов часто возникают два вопроса относительно использования оперативной памяти сервером Firebird:

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

Попробуем ответить на оба.

Оперативная память сервера распределяется для:

  1. Программного кода, стека и данных ядра операционной системы. По нашим наблюдениям операционная система Windows Server 2003 требует "для себя" порядка 0.5 Гб. Можно предположить, что требования Windows Server 2008 будут еще выше.
  2. Выполняющихся на сервере приложений и служб. [1]
  3. Дискового кэша.
  4. Сервера баз данных Firebird.

Каждый серверный процесс Firebird архитектуры Super[2] или Classic использует следующее количество памяти:

  1. Память на размещение образа процесса, переменных, стека. Порядка 20 Мб.
  2. Кэш страниц базы данных. Размер определяется как размер страницы, умноженный на количество страниц в буфере. Устанавливается при разбэкапе базы или утилитой gfix. В последнем случае можно поменять только количество страниц.
  3. Блок памяти для сортировки данных и размещения временных таблиц. Определяется переменной TempCacheLimit в файле конфигурации firebird.conf. По умолчанию, для Super установлен в 64 Мб, для Classic — 8 Мб.

Зависимость производительности сервера Firebird от размера кэша операционной системы

При считывании данных Firebird сначала пытается найти нужные страницы в своем кэше. Если их там нет -- обращается к операционной системе. Операционная система, в свою очередь, проверяет нет ли нужных данных в ее кэше и только потом начинает операцию чтения с дискового устройства. При использовании сервера классической архитектуры, размер буфера каждого серверного процесса устанавливается небольшим (обычно 800-1000 страниц). Таким образом, производительность Firebird будет в большей степени определяться размером дискового кэша операционной системы. То же верно и для архитектуры SuperServer, когда размер базы данных намного превышает размер выделенного буфера.

При использовании 32-х разрядной операционной системы размер файлового кэша ограничен 1-1.5 Гб. Практического ограничения нет при использовании 64-х разрядной ОС. При этом стоит учитывать, что только начиная с Windows 7 и Windows Server 2008 R2 решена проблема с поглощением файловым кэшем всей доступной оперативной памяти и вытеснением памяти других процессов в своп[3].

Использование кэша операционной системы для размещения файлов сортировки

При сортировке данных, объема большего чем TempCacheLimit, создается временный файл на диске. На больших базах размер такого файла может достигать внушительных величин — от гигабайта и более. Сортировка требуется, если в запросе присутствует секция ORDER BY, GROUP BY или UNION и оптимизатор не может использовать индекс. Записи результирующей выборки в файле сортировки помещаются целиком, к ним добавляется служебная информация и информация о ключе. Например, пусть выборка получена запросом:

 SELECT description FROM gd_document ORDER BY 1

По полю description в базе данных индекса нет, а это значит что будет создан файл сортировки. В него будут выгружены все значения поля description из всех строк таблицы gd_document. Не важно, что в подавляющем большинстве записей оно пустое. Данное поле имеет тип VARCHAR (180), однобайтовая кодировка Win1251.

Мы провели тест на одной из рабочих баз:

  • Версия сервера: Firebird 2.5 RC3
  • Выполняемый запрос: SELECT description FROM gd_document ORDER BY 1
  • Количество записей в gd_document: 31 808 358
  • Тип поля description: VARCHAR (180), однобайтовая кодировка
  • Размер данных в поле description: 11 376 340 байт
  • Размер файла сортировки: 18 210 586 624 байт
  • Время выполнения запроса: ~2 часа

Размер данных определялся запросом:

 SELECT SUM(COALESCE(CHAR_LENGTH(description), 0)) FROM gd_document

Таким образом, в нашем примере на каждый миллион записей в исходной таблице файл сортировки увеличивался почти на 600 Мб.

Информацию по структуре и размеру файла сортировки можно получить на форумах поддержки Firebird. Приводим цитаты разработчиков сервера Дмитрия Еманова и Влада Хорсуна:

В запись сортировки попадает декларированная длина поля, выровненная до 4-х байтной границы, плюс служебная информация (как минимум номера записи и транзакции).
<...>
любая INTL-строка дважды кладется в сортировщик, первый раз как ключ (преобразованная по collate), а второй раз как данные (as is), чтобы именно ее и вернуть при фетче из сортировщика. Ведь преобразование из ключа в строку в общем случае неоднозначно, а саму запись мы после сортировки уже не читаем.
<...>
Если Collate у столбца словарный (PXW_CYRL и т.п.), то храним два байта на символ.

Операционная система Windows ведет себя следующим образом: если оперативной памяти достаточно, то временный файл удерживается в памяти. Физической записи на диск не происходит. Следует обратить внимание, что память, используемая под временные файлы сортировки, не отображается в Task Manager. Поэтому, если Task Manager при подключенных пользователях показывает общее использование памяти 40-60%, это еще не значит, что памяти достаточно и расширять ее не имеет смысла.

Папки для размещения временных файлов определяются параметром TempDirectories в файле конфигурации firebird.conf. Если он не задан (по умолчанию), используются пути прописанные в переменных окружения FIREBIRD_TMP, TEMP, TMP.

Следует помнить, что скорость сортировки данных, когда временный файл умещается в оперативной памяти и когда он записывается на диск, различается в сотни раз.

Пример расчета потребности в памяти для сервера архитектуры Classic

  • Размер базы данных: 10 Гб
  • Планируемое количество подключений: 70
  • Размер страницы: 8192 байт
  • Размер буфера: 1000 страниц
  • Параметры по умолчанию в файле конфигурации

Память под процессы:

 70 * (20 + 8 + 8192 * 1000 / 1000000) = 2.5 Гб

Память под собственные нужды ОС[4]:

 0.5 Гб

Память под файлы сортировки[5]:

 2 Гб

Память под дисковый кэш:

 6 Гб

Таким образом, получаем:

 2.5 + 0.5 + 2 + 6 = 11 Гб

это ориентировочная потребность в памяти для комфортной работы всех пользователей. Разумеется, если удастся установить больше памяти — это ни коим образом не повредит и только улучшит производительность.

Примечания

  1. В идеале сервер должен быть выделен исключительно для работы с базой данных. Остерегайтесь антивирусов, особенно в режиме постоянной проверки дисковых операций. Нам сообщали, что сервер MS SQL способен "перераспределять" под себя основные ресурсы компьютера, существенно ухудшая производительность других приложений. Если сервер выполняет роль контроллера домена, убедитесь что база данных Active Directory находится на отдельном жестком диске. Подробную информацию о памяти и выполняющихся приложениях вы можете получить с помощью бесплатной утилиты Process Explorer.
  2. Подробнее об архитектурах сервера Firebird можно прочитать здесь.
  3. You experience performance issues in applications and services when the system file cache consumes most of the physical RAM
  4. Приведен размер памяти, в случае, когда на сервере не работает другое ПО, кроме Firebird.
  5. Следующие числа получены нами эмпирическим путем в результате наблюдения за десятками баз данных, работающими в реальных условиях.
Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты