Эта страница переведена машинным переводом. Читайте английский оригинал. English

Библиотека IBSurgeon

23 дополнительных способа ускорить Firebird

Алексей Ковязин, IBSurgeon, [email protected], 08-янв-2019

Переводы: Португальский

Почему «ещё 23»?

Некоторые из вас помнят статью « 45 способов ускорить Firebird», которая была опубликована в мае 2016 года. Пришло время опубликовать следующую серию советов и рекомендаций, основанных в основном на опыте оптимизации и обслуживания баз данных и серверов Firebird с большим количеством подключений (1000+).

1. Установите схему электропитания «Высокая производительность» в Windows Server 2016 и 2019

По умолчанию в Windows Server установлена схема электропитания «Сбалансированная», которая не подходит для серверов баз данных. Установите «Высокая производительность» и получите примерно +20% производительности для операций, интенсивно использующих ЦП. Это можно сделать онлайн, без перезагрузки или перезапуска. На рисунке ниже показан график ЦП, демонстрирующий преимущество схемы «Высокая производительность»:

Более подробно о наших тестах с планами электропитания Windows можно узнать здесь.

2. Включите «Взаимодействие с рабочим столом» для Classic на Windows

Если вы используете Firebird с архитектурой Classic на Windows, установите флажок «Разрешить службе взаимодействовать с рабочим столом». Без этого параметра ресурс «куча рабочего стола» ограничивается Windows, и Firebird не может открыть более 250-300 подключений (зависит от метаданных базы данных и связанного потребления памяти) - возникнет ошибка Out Of Memory.

3. Осторожно: контроллер домена

Проблема в том, что Windows с ролью контроллера домена отключает кэш записи на диске с базой данных Active Directory.

Это влияет на Firebird по-разному (а также на другие приложения, конечно), и производительность значительно хуже, чем на серверах без ролей Active Directory.

Обратите внимание, что эта проблема затрагивает такие популярные версии Windows, как Windows Small Business Server 2011, а также другие версии с контроллером домена.

4. Увеличьте лимит «max open files» на Linux

Если вы используете Linux в качестве сервера баз данных, не забудьте настроить лимиты для Firebird. Проверьте лимиты для вашего процесса Firebird (SuperServer или SuperClassic) следующей командой:

Code
cat /proc//limits

и обратите внимание на строку с максимальным количеством открытых файлов.

Firebird может использовать до 4 дескрипторов на одно подключение, и если у вас что-то вроде этого:

Code
Max open files 4096 4096 files

это означает, что общее количество подключений, обслуживаемых процессом Firebird, будет ограничено примерно 1000.

Обратите внимание - если на сервере 4 базы данных, подключение к каждой базе учитывается.

Установите больше - я рекомендую 65535.

Не забудьте проверить после перезапуска процесса Firebird: применилось ли изменение или нет.

Для архитектуры Classic необходимо проверить и увеличить лимиты для пользователя «firebird».

5. Используйте современный Linux

Да, я понимаю, что этот совет тривиален, но я много раз видел хорошее улучшение производительности после миграции с CentOS 6 на 7, с Ubuntu 12 на 16 (на том же оборудовании!), так что теперь это обязательная рекомендация для серверов баз данных с более чем 250-300 подключениями. Современный Linux является предварительным условием для дальнейших шагов оптимизации.

Рекомендуемые версии Linux: CentOS 7.x и Ubuntu 16, 18.

6. Зарезервируйте 40% ОЗУ для файлового кэша на Windows

Диспетчер памяти ОС имеет особенности, касающиеся выделения памяти, и по умолчанию Windows требует 40% ОЗУ для файлового кэша.

К сожалению, плохой инструмент «Диспетчер задач Windows» показывает память, используемую для файлового кэша, как «свободную», и некоторые администраторы пытаются заставить Firebird потреблять всю эту свободную память, поэтому они устанавливают очень высокие значения параметра DefaultDBCachePage в firebird.conf, что обычно приводит к свопингу.

Всегда используйте инструмент RAMMap, чтобы увидеть фактическое использование памяти на Windows.

Эмпирическое правило для Windows Server (выделенного для использования в качестве сервера Firebird) следующее: память Firebird (рабочий набор) должна быть меньше 40% от общего объема ОЗУ. Если общий размер рабочих наборов для всех процессов превышает 50%, Windows может начать свопинг.

Обратите внимание: «зарезервировать» здесь означает не только «не устанавливать слишком много буферов страниц в Firebird», но также, что важно, ограничить использование памяти другим программным обеспечением. Например, если у вас есть MS Exchange или MSSQL на том же сервере, что и Firebird, убедитесь, что вы ограничили их аппетиты к памяти.

Если вам интересно узнать подробности, я записал вебинар, посвященный управлению памятью в Firebird:

7. Зарезервируйте 30% ОЗУ для файлового кэша на Linux

Linux работает с файловым кэшем иначе, чем Windows, и в целом объем ОЗУ, используемый для файлового кэша, может быть значительно меньше, чем на Windows, без заметного ухудшения производительности Firebird. Однако для гарантии высокой производительности системы с большим количеством подключений, особенно на Classic и SuperClassic, хорошей идеей будет зарезервировать 30% ОЗУ для файлового кэша.

8. Используйте irqbalance на Linux

irqbalance часто улучшает производительность Firebird и балансировку нагрузки на ЦП на серверах с большим количеством ядер.

9. Для виртуальных машин - остерегайтесь Memory Overcommit

Виртуальная машина может быть настроена с большим объемом памяти, чем физически существует на хост-машине - с помощью функции, известной как Memory Overcommit (название может отличаться в разных системах виртуализации). Это означает, что в случае пика потребления памяти (на ВМ с сервером баз данных или на соседней ВМ) может начаться свопинг, что приведет к значительным задержкам. Для высокопроизводительной ВМ, предназначенной для сервера баз данных, вся память должна быть статической.

10. Для виртуальных машин - проверьте лимиты ВМ

Часто ВМ создаются с лимитами ЦП и ввода-вывода по умолчанию, которые могут быть очень низкими, например 50 IOPS и 10% ЦП. Проверьте настройки вашей серверной ВМ и удалите все лимиты - высокопроизводительный сервер баз данных должен иметь все возможные ресурсы ЦП, пропускной способности и ввода-вывода.

11. Очищайте временные файлы Firebird

Firebird создает множество временных файлов для различных операций: сортировки, обработки BLOB, трассировки. Эти файлы хранятся в следующих местах: на Windows C:\ProgramData\firebird, на Linux / tmp / firebird

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

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

12. Не забывайте включать файловый кэш при большом кэше Firebird

Как вы знаете, кэш Firebird (также называемый «буферы страниц») задается параметром DefaultDBCachePages в firebird.conf/databases.conf или непосредственно в заголовке базы данных.

В Firebird 3 SuperServer размер этого кэша может быть установлен очень большим, но важно помнить о другом параметре: FileSystemCacheThreshold.

Если FileSystemCacheThreshold меньше, чем DefaultDBCachePages или буферы страниц, файловый кэш операционной системы не будет использоваться, что может привести к проблемам с производительностью.

В 99% случаев лучше иметь включенный файловый кэш.

Чтобы это гарантировать, всегда устанавливайте параметры по следующему правилу:

  • DefaultDBCachePages = X
  • FileSystemCacheThreshold = X+ N, N>1

Существуют редкие случаи, когда отключение файлового кэша улучшает производительность - если у вас есть такой пример, пожалуйста, свяжитесь со мной - [email protected]!

13. Ускорьте работу базы данных безопасности

Каждое подключение к базе данных Firebird устанавливает соединение с базой данных безопасности (security3.fdb в случае Firebird 3) и выполняет несколько операций чтения и записи (страницы транзакций, страница заголовка). Если у вас частые подключения, производительность вашей базы данных безопасности может стать проблемой.

Как минимум, вы можете сделать следующее:

  • Увеличьте page buffers для securityN.fdb (эмпирический оптимум - 256 буферов)
  • Переместите security3.fdb на быстрый диск (это стандартная функция в Firebird 3, в 2.5 потребуется переустановка)

Затем можно отключить Forced Writes для базы данных безопасности - небольшой риск повреждения в этом случае не проблема.

Самый радикальный способ - сделать базу данных безопасности доступной только для чтения - это исключит все записи в нее.

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

14. Попробуйте SuperClassic на Firebird 3

В Firebird 3 архитектура SuperServer активно рекламировалась как ultimate решение для производительности, но есть некоторые типы нагрузки, которые показывают лучшую производительность с SuperClassic (но не Classic - он всегда работает медленнее, чем SuperServer/SuperClassic).

Как безопасно провести этот эксперимент? Выполните следующие шаги:

Чтобы попробовать SuperClassic

  1. Установите в firebird.conf
  2. ServerMode=SuperClassic
  3. DefaultDbCachePages=1024
  4. gfix -buff 0
  5. Перезапустите Firebird

Чтобы вернуться к SuperServer

  1. Установите в firebird.conf
  2. ServerMode=SuperServer
  3. DefaultDbCachePages=N # N*page size*databases_count < 25% RAM
  4. FileSystemCacheThreshold = N+1
  5. gfix -buff 0
  6. Перезапустите Firebird

Пожалуйста, напишите мне ([email protected]) о результатах эксперимента, мне интересно увидеть результаты.

15. Большая база данных? Увеличьте размер страницы

По умолчанию базы данных Firebird имеют следующие размеры страниц:

  • 2.5 - 4096 байт
  • 3.0 - 8192 байт

Однако максимальный размер страницы - 16K (в 4.0 - 32K).

Для баз данных более 100 ГБ в 95% случаев лучше иметь максимально доступный размер страницы, чтобы:

  • Уменьшить глубину индексов. Рекомендуется иметь индексы с глубиной меньше или равной 3. Индексы с глубиной 4 и 5 будут работать значительно медленнее
  • Увеличить использование оперативной памяти. Кэш Firebird задается в страницах, 1000 страниц с размером 8K будут 8 МБ фактической памяти, а с 16K - 16 МБ.
  • Уменьшить количество системных страниц. Это ускорит доступ к записям больших таблиц (меньше переходов указатель-указатель-страница данных) и поможет при подготовке больших SQL-запросов. Чтобы увеличить размер страницы базы данных, необходимо сделать резервную копию с помощью инструмента gbak, а затем восстановить с параметром -page ( gbak -c -page 16384).

Обратите внимание: если у вас есть база данных с множеством маленьких BLOB-полей, увеличение размера страницы может как уменьшить, так и увеличить фрагментацию, и трудно предсказать, увеличит ли это производительность или уменьшит.

16. Не используйте флаг no_reserve

Флаг no_reserve заставляет Firebird не резервировать свободное пространство (30%) на страницах данных для возможных версий записей, которые возникают после UPDATE или DELETE. Этот флаг позволяет хранить данные более компактно (и размер базы данных тоже меньше), но в случае UPDATE/DELETE все изменения попадают на новую страницу данных. В результате в базе данных с флагом no_reserve операции UPDATE/DELETE выполняются медленнее.

Поэтому, если ваша база данных не только для чтения, я рекомендую удалить флаг no_reserve.

Как проверить, установлен ли он или нет - смотрите строку Attributes в выводе

Code
gstat -h database

Как отключить:

Code
gfix -use reserve database

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

Однако для достижения полного эффекта необходимо сделать резервную копию базы данных с помощью gbak, а затем восстановить - в этом случае все страницы данных будут с зарезервированным пространством.

Обратите внимание: размер базы данных увеличится после удаления no_reserve флага и резервного копирования/восстановления.

17. Установите высокий начальный размер таблицы блокировок Firebird

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

Таблица блокировок Firebird может автоматически увеличиваться, но ее увеличение - медленная операция, которая может привести к микро-зависаниям. Таблица блокировок может только расти, начиная с начального размера (он задается в firebird.conf).

Чтобы предотвратить многократные циклы увеличения таблицы блокировок, хорошей идеей будет следить за размером таблицы блокировок в конце рабочего периода (день, неделя и т.д.), а затем установить его как начальный размер в firebird.conf.

LockMemSize=99999999

Для справки: LockMemSize на системах с высокой нагрузкой с ~1000 пользователей обычно ниже 200 МБ.

18. Используйте fb_lock_print для подсчета количества подключений к базе данных

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

Часто разработчики используют запрос SELECT count(*) FROM MON$ATTACHMENTS для получения этого значения, но это не оптимальный способ: частые запросы к таблицам MON$ могут быть нагрузкой для базы данных, поэтому лучше использовать альтернативу:

Выполните

fb_lock_print -d database_name | alias

и проверьте значение Owners - оно покажет текущее количество подключений к базе данных.

19. Избегайте ненужных LEFT JOIN

Часто я вижу запросы с такой конструкцией:

T1 LEFT JOIN T2 ON (…) WHERE T2.Field_condition

По сути, условие на T2 исключает NULL из вывода LEFT JOIN T2, поэтому можно изменить LEFT JOIN на INNER JOIN - это не повлияет на результат запроса.

INNER JOIN дает больше свободы оптимизатору Firebird, и в современных версиях Firebird он оптимизируется гораздо лучше, чем LEFT.

Особенно это имеет смысл в следующих случаях:

  • Нет условия для T1 в WHERE
  • T2 - небольшая таблица

20. Избегайте ненужного подсчета записей

Еще одна распространенная ошибка в сложных запросах к базе данных и хранимых процедурах - использование select count() только для проверки существования записи.

Следующий запрос прочитает все записи согласно условию1:

Code
(select count(*)…. where condition11) >0

Лучше использовать эту конструкцию вместо этого

Code
Exists(select first 1 id where condition1)

Если condition1 возвращает более одной записи, предложенный вариант будет намного быстрее, потому что он не читает все записи, а останавливается после первой полученной записи.

21. Избегайте ненужной сортировки в хранимых процедурах

Упорядочивание результатов запроса внутри хранимой процедуры должно быть оправдано бизнес-логикой.

Например, в примере хранимой процедуры ниже предложение ORDER BY бесполезно с точки зрения бизнес-логики, но добавляет ненужную операцию сортировки.

Code
create or alter procedure NEW_PROCEDURE
returns (
    SUMX double precision)
as
declare variable _amount double precision;
begin
for select T1.amount from Table1 t1 where ....
    order by id
    into :_amount
    do
    begin
     sumx=sumx+_amount
    end;
  suspend;
end

Проверьте свой PSQL-код на подобные ситуации и удалите бесполезные ORDER BY (а также distinct и UNION).

22. Не держите запросы в подготовленном состоянии без необходимости

Часто мы видим 500-1000 подготовленных операторов в каждом подключении (это можно проверить с помощью запросов MON$).

Подавляющее большинство из них выполняется только один раз, а затем просто сидят в оперативной памяти, увеличивая рабочий набор Firebird и замедляя запросы MON$.

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

23. Всегда закрывайте запросы с большой сортировкой

Пока SQL-запрос с сортировкой (ORDER BY, GROUP BY, UNION, distinct) не закрыт, Firebird сохраняет отсортированные записи в памяти. Размер памяти, выделяемой для сортировки, задается параметром TempCacheLimit в firebird.conf, по умолчанию он составляет 64 МБ.

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

Рекомендация - своевременно закрывать все такие запросы.

Вопросы?

Пожалуйста, не стесняйтесь связаться со мной по любым вопросам: [email protected]!