прошлой статье
В прошлой статье я рассмотрел пять вариантов перехвата функций включая их вариации.
Правда в ней я оставил не рассмотренными две неприятных ситуации:
1. Вызов перехваченной функции в тот момент,
Внезапный direct I/O
Итак, СУБД Firebird и InterBase обычно используют файловый кэш при работе с БД. Вернее сказать, не «используют кэш», а при открытии файла БД указывают опции, которые включают или выключают этот кэш в определенных случаях.
Одновременно, они используют свой собственный кэш страниц БД.
Самый первый и известный случай изменения режима , это режим Forced Writes, т.е. в терминах CreateFile (Windows) включение (ON) или выключение (OFF) флага FILE_FLAG_WRITE_THROUGH. При ON операционная система осуществляет запись сразу на диск (или в контроллер raid, и т.д.). При OFF операционная система кэширует изменяемые страницы в RAM (подробнее о режимах кэша Windows).
Однако, у Firebird и InterBase существует понятие careful writes, когда изменяемые страницы записываются на диск в таком порядке, чтобы в случае внезапного сбоя (например, reset) база данных осталась максимально целой. Поскольку при OFF (включенном write cache ОС) порядок записи определяется операционной системой, а не СУБД, в случае reset БД может оказаться, скажем, в «физически нецелостном» состоянии.
Например, если добавляется новая запись, а места на страницах БД для этого нет, то создается новая страница, запись размещается на ней, затем ссылка на страницу добавляется в Pointer pages таблицы, после чего в соответствующую inventory pages для новой страницы заносится флаг «занято».
Если все это попадает в кэш ОС, то страница inventory pages может попасть на диск раньше новой страницы с записью, в результате чего при reset окажется, что страница как бы занята, и таблица ссылается на нее, а на деле в этой странице мусор (еще ничего не записано).
Что интересно, до определенного момента в Firebird на Linux режим Forced Writes = ON не поддерживался, т.е. всегда было OFF (исправлено в FB 2.1)
Вторым из режимов кэша, или режимов открытия файлов, является флаг FILE_FLAG_NO_BUFFERING (Windows), который выключает кэш ОС для этого файла вообще, т.е. в том числе и на чтение.
Мы давно экспериментировали с этим флагом в Yaffil, и выяснили, что на обычных дисках производительность резко просаживается (у IB и FB, да и у Yaffil, собственный кэш не умеет делать prefetch, в отличие от ОС), а также, что худший вариант — когда размер страницы не совпадает с размером кластера файловой системы.
В общем, по результатам теста этот флаг было решено оставить в покое.
Со временем кэш дисков, контроллеров и вообще систем хранения сильно вырос, и стал достаточно умным. Так что на некоторых устройствах есть смысл во включении Direct I/O.
Для InterBase возможность отключить кэш ОС была введена в версии XE.
В Firebird такая возможность появилась в 2.5. Для всех баз на сервере direct I/O можно включить путем установки опции FileSystemCacheThreshold=0 в firebird.conf.
Что интересно, режим direct I/O включается не только этим нулем, а и в том случае, если указанный размер кэша БД (DefaultDBCachePages в firebird.conf или page buffers в конкретной БД) больше, чем FileSystemCacheThreshold.
То есть, поскольку FileSystemCacheThreshold по умолчанию 65536, то режим direct I/O включится, если размер кэша в конфиге или БД указан больше этого значения.
Попасть на эти грабли могут разве что пользователи Firebird с архитектурой SuperServer, потому что у Classic и SuperClassic раздельный кэш БД, и выставлять значения кэша больше 65к страниц никому и в голову не придет — сервер тут же начнет отжирать память. Например, для страницы 8к 65к страниц кэша станут 512 мегабайтами RAM, потребляемыми на каждого пользователя.
С другой стороны, у SuperServer кэш БД общий для всех пользователей, и поэтому вполне разумно указать его побольше, особенно если размер БД как минимум 1 гигабайт.
Но как только вы включите такой кэш, «внезапно» для БД отрубится файловый кэш операционной системы (если не изменить параметры по умолчанию в firebird.conf).
Хорошо это или плохо — нужно проверять в конкретном случае. Ваша дисковая подсистема может оказаться настолько крутой, что отключение файлового кэша ОС для БД улучшит производительность, или, по крайней мере, освободит память ОС для других целей.
Но если нет — при задирании размера кэша БД вдруг может случиться и падение производительности.
Дополнения:
- на Linux указанные режимы открытия файлов это O_SYNC и O_DIRECT.
- после включения direct I/O режим Forced Writes уже не имеет значения (будет всегда ON)
- в Firebird 2.5.2 исправлена еще одна проблема с кэшем Windows.
Lazy Delphi Builder 1.8.6.240 от 28-04-2013 для Delphi XE4 и XE5
Что нового (вкратце):Поддержка Delphi XE4. И на всякий случай, сразу и Delphi XE5, — вдруг выйдет через месяц =) Профили (мини). Теперь можно сохранять профили
Lazy Delphi Builder 1.8.6.240 от 28-04-2013 для Delphi XE4 и XE5
Что нового (вкратце):Поддержка Delphi XE4. И на всякий случай, сразу и Delphi XE5, — вдруг выйдет через месяц =)
Профили (мини). Теперь можно сохранять профили групп настроек для дальнейшего использования. Сделано для: выходных папок, настроек билда, переменных окружения и других мелочей (см. ниже).
Изменён формат хранения списков в файлах LazyDBP и ini. Теперь без цифр – а это значит, что сравнить два файла в Diff-viewer-е станет совсем просто. И кстати, теперь все настройки будут сохраняться в подкаталоге Data. Новый формат профилей не имеет обратной совместимости со старым. Но возможность сохранить в старом формате осталась в Save As диалоге.
Поддержка нескольких выражений в фильтре дерева (через точку с запятой “;”)
Появилась возможность вместо dcc32.exe подставлять свой файл. Это…
[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
Атомарные операции
Буквально на днях ко мне обратились с вопросом.
А зачем нужен префикс LOCK, или его аналог InterlockedDecrement при вызове процедуры _LStrClr из модуля System. Данная процедура
Использование Lua скриптов в составе ПО
Представьте себе ситуацию, ваше приложение реализует достаточно большой функционал для пользователя и он им пользуется достаточно успешно на протяжении достаточно большого периода времени. Но вот
Головокружительные возможности DI и Delphi Spring. Часть 9. Один интерфейс – несколько реализаций.
Это последний перевод из серии про внедрение зависимостей на примере использования Delphi Spring. Это перевод публикации Ника Ходжеса от 07 ноября 2011 года: Getting Giddy
Головокружительные возможности DI и Delphi Spring. Часть 9. Один интерфейс – несколько реализаций.
Это последний перевод из серии про внедрение зависимостей на примере использования Delphi Spring.
Это перевод публикации Ника Ходжеса от 07 ноября 2011 года: Getting Giddy with Dependency Injection and Delphi Spring #9 – One Interface, Many Implementations. (перевод сделан с разрешения автора). Предыдущие публикации Я не переводил части с 1й по 5ю, потому что мне было лень — там очень много текста, и, по моему скромному мнению, эти части не содержат конкретной информации об использовании Delphi Spring, а постепенно подводят к необходимости использования Dependency Injection. Причём, Ник ведёт к этому слишком длинным и запутанным путём. См. Ссылки по теме. DI и Delphi Spring. Часть 5. Основы Delphi Spring. DI и Delphi Spring. Часть 6. Обойдёмся без конструктора. DI и…
[[ This is a content summary only. Visit my website for full links, other content, and more! ]]
Лучшее в Delphi блогах за 2012 год
Все лучшие публикации по Delphi за 2012 год в одном месте. Радует, что качество публикаций растёт с каждым годом. Рад видеть среди новых авторов Александра