Spec-Zone.ru › SQLite

Интерфейс операционной системы SQLite или "VFS"

Содержание
1. Введение
2. VFS по отношению к остальной части SQLite
3. Несколько VFS
3.1. Стандартные Unix VFS
3.2. Стандартные Windows VFS
3.3. Указание используемого VFS
3.4. VFS-шимы
3.5. Другие примеры VFS
4. Реализации VFS

1. Введение

В данной статье описывается уровень переносимости операционной системы SQLite или "VFS" — модуль в нижней части стека реализации SQLite, обеспечивающий переносимость между операционными системами.

2. VFS по отношению к остальной части SQLite

Внутреннюю организацию библиотеки SQLite можно представить в виде стека модулей, показанного справа. Компоненты Токенизатор, Парсер и Генератор кода используются для обработки SQL-запросов и преобразования их в исполняемые программы на языке виртуальной машины или байткоде. Грубо говоря, эти три верхних уровня реализуют sqlite3_prepare_v2(). Байткод, сгенерированный тремя верхними слоями, представляет собой предготовленный запрос. Модуль Виртуальной машины отвечает за выполнение байткода SQL-запроса. Модуль B-дерева организует файл базы данных в несколько хранилищ ключей/значений с упорядоченными ключами и логарифмической производительностью. Модуль страницы отвечает за загрузку страниц файла базы данных в память, за реализацию и управление транзакциями, а также за создание и поддержание файлов журнала, предотвращающих повреждение базы данных после сбоя или отключения питания. Интерфейс ОС — тонкое абстрагирование, предоставляющее общий набор процедур для адаптации SQLite к работе в различных операционных системах. Грубо говоря, нижние четыре слоя реализуют sqlite3_step().

Эта статья посвящена нижнему слою.

Интерфейс операционной системы — также называемый "VFS" — обеспечивает переносимость SQLite между операционными системами. Всякий раз, когда любой из других модулей в SQLite нуждается в общении с операционной системой, они вызывают методы в VFS. Затем VFS вызывает специфичный для операционной системы код, необходимый для удовлетворения запроса. Таким образом, портирование SQLite в новую операционную систему сводится к написанию нового уровня интерфейса ОС или "VFS".

3. Несколько VFS

Стандартное дерево исходного кода SQLite содержит встроенные VFS для Unix и Windows. Альтернативные VFS можно добавить во время запуска или во время работы с помощью интерфейса sqlite3_vfs_register().

Одновременно можно зарегистрировать несколько VFS. Каждый VFS имеет уникальное имя. Разные соединения с базой данных в одном процессе могут использовать разные VFS одновременно. В этом случае, если у одного соединения с базой данных открыто несколько файлов баз данных с помощью команды ATTACH, то каждая присоединённая база данных может использовать другой VFS.

3.1. Стандартные Unix VFS

Сборка Unix поставляется с несколькими встроенными VFS. По умолчанию для Unix используется VFS под названием "unix", который используется в большинстве приложений. Другие VFS, которые могут быть найдены в Unix (в зависимости от параметров компиляции), включают:

  1. unix-dotfile — использует блокировку файлов с точкой вместо рекомендательных блокировок POSIX.

  2. unix-excl — получает и удерживает эксклюзивную блокировку файлов базы данных, предотвращая доступ к базе данных другим процессам. Также хранит wal-индекс в куче, а не в общей памяти.

  3. unix-none — все операции блокировки файлов являются операциями бездействия.

  4. unix-namedsem — использует именованные семафоры для блокировки файлов. Только VXWorks.

Различные VFS Unix отличаются только способом обработки блокировки файлов — они совместно используют большую часть своей реализации и все находятся в одном файле исходного кода SQLite: os_unix.c. Обратите внимание, что за исключением "unix" и "unix-excl", различные VFS Unix используют несовместимые реализации блокировки. Если два процесса обращаются к одной и той же базе данных SQLite с помощью разных VFS Unix, они могут не видеть блокировки друг друга и могут мешать друг другу, что приведёт к повреждению базы данных. В частности, VFS "unix-none" вообще не выполняет блокировку и легко приведёт к повреждению базы данных, если его используют два или более соединений с базой данных одновременно. Разработчикам рекомендуется использовать только "unix" или "unix-excl", если нет веских причин поступить иначе.

3.2. Стандартные Windows VFS

Сборка Windows также поставляется с несколькими встроенными VFS. По умолчанию в Windows используется VFS под названием "win32", который используется в большинстве приложений. Другие VFS, которые могут быть найдены в сборках Windows, включают:

  1. win32-longpath — аналогично "win32", за исключением того, что имена путей могут иметь длину до 65534 байтов, в то время как имена путей в "win32" имеют максимальную длину 1040 байтов.

  2. win32-none — все операции блокировки файлов являются операциями бездействия.

  3. win32-longpath-none — сочетание "win32-longpath" и "win32-none" — поддерживаются имена путей большой длины, и все операции блокировки являются операциями бездействия.

Как и в случае с Unix, большая часть кода для различных VFS Windows совмещена.

3.3. Указание используемого VFS

Всегда существует один VFS, который является VFS по умолчанию. В системах Unix VFS "unix" является по умолчанию, а в Windows — "win32". Если не предпринимать никаких других действий, новые соединения с базой данных будут использовать VFS по умолчанию.

VFS по умолчанию можно изменить, зарегистрировав или повторно зарегистрировав VFS с помощью интерфейса sqlite3_vfs_register() со вторым параметром 1. Следовательно, если процесс (Unix) хочет всегда использовать VFS "unix-nolock" вместо "unix", следующий код будет работать:

sqlite3_vfs_register(sqlite3_vfs_find("unix-nolock"), 1);

Альтернативный VFS также можно указать в качестве четвёртого параметра функции sqlite3_open_v2(). Например:

int rc = sqlite3_open_v2("demo.db", &db, SQLITE_OPEN_READWRITE, "unix-nolock");

Наконец, если имена файлов URI были включены, то альтернативный VFS можно указать, используя параметр "vfs=" в URI. Этот метод работает с sqlite3_open(), sqlite3_open16(), sqlite3_open_v2() и при присоединении новой базы данных к существующему соединению с базой данных с помощью ATTACH. Например:

ATTACH 'file:demo2.db?vfs=unix-none' AS demo2;

VFS, указанный в URI, имеет наивысший приоритет. После этого идёт VFS, указанный в качестве четвёртого аргумента функции sqlite3_open_v2(). В противном случае используется VFS по умолчанию.

3.4. VFS-шимы

С точки зрения верхних слоёв стека SQLite, каждый открытый файл базы данных использует ровно один VFS. Но на практике конкретный VFS может быть всего лишь тонким оболочкой вокруг другого VFS, выполняющего реальную работу. Мы называем оболочку VFS "шимом".

Простым примером шима является VFS "vfstrace". Это VFS (реализованный в файле исходного кода test_vfstrace.c), который записывает сообщение, связанное с каждым вызовом метода VFS, в файл журнала, а затем передаёт управление другому VFS для выполнения фактической работы.

3.5. Другие примеры VFS

Ниже приведены другие реализации VFS, доступные в общедоступном дереве исходного кода SQLite:

  • appendvfs.c - Этот VFS позволяет прикреплять базу данных SQLite к концу другого файла. Это можно использовать, например, для добавления базы данных SQLite в конец исполняемого файла, чтобы при запуске он мог легко найти присоединённую базу данных. Оболочка командной строки командной строки будет использовать этот VFS, если запущена с параметром --append, а её команда .archive будет использовать его при заданном флаге --append.

  • test_demovfs.c - Этот файл реализует очень простую VFS под названием «demo», которая использует функции POSIX, такие как open(), read(), write(), fsync(), close(), fsync(), sleep(), time() и так далее. Эта VFS работает только на системах Unix. Но она не предназначена для замены стандартной VFS «unix», используемой по умолчанию на платформах Unix. VFS «demo» намеренно сохраняется очень простой, чтобы её можно было использовать в качестве учебного пособия или шаблона для создания других VFS или для портирования SQLite на новые операционные системы.

  • test_quota.c - Этот файл реализует подключаемый модуль «quota», который накладывает ограничения на суммарный размер файлов базы данных в группе файлов. Для определения «групп квот» используется вспомогательный интерфейс. Группа квот — это набор файлов (файлы базы данных, журналы и временные файлы), имена которых соответствуют шаблону GLOB. Сумма размеров всех файлов в каждой группе квот отслеживается, и если эта сумма превышает порог, определённый для группы квот, вызывается функция обратного вызова. Эта функция обратного вызова может либо увеличить порог, либо заставить операцию, которая бы превысила квоту, завершиться с ошибкой SQLITE_FULL. Одним из применений этого подключаемого модуля является наложение ограничений на ресурсы баз данных приложений в Firefox.

  • test_multiplex.c - Этот файл реализует подключаемый модуль, который позволяет файлам базы данных превышать максимальный размер файла на базовой файловой системе. Этот подключаемый модуль предоставляет интерфейс для верхних шести слоёв SQLite, который заставляет выглядеть, как будто используются очень большие файлы, когда на самом деле каждый такой большой файл разбивается на множество меньших файлов на базовой системе. Этот подключаемый модуль использовался, например, для увеличения размера баз данных более 2 гигабайт на файловых системах FAT16.

  • test_onefile.c - Этот файл реализует демонстрационную VFS под названием «fs», которая показывает, как SQLite можно использовать на встроенном устройстве, на котором отсутствует файловая система. Содержимое записывается непосредственно в базовое устройство хранения. VFS, полученный из этого демонстрационного кода, может использоваться устройством с ограниченным объёмом флэш-памяти для того, чтобы SQLite работал как файловая система для флэш-памяти на устройстве.

  • test_journal.c - Этот файл реализует подключаемый модуль, используемый во время тестирования SQLite, который проверяет, что база данных и журнал отката записываются в правильном порядке и «синхронизированы» в соответствующие моменты времени, чтобы гарантировать, что база данных может восстановиться после потери питания или жёсткой перезагрузки в любое время. Подключаемый модуль проверяет несколько инвариантов работы баз данных и журналов отката и генерирует исключения, если какой-либо из этих инвариантов нарушается. Эти инварианты, в свою очередь, гарантируют, что база данных всегда может быть восстановлена. Запуск большого набора тестовых случаев с помощью этого подключаемого модуля предоставляет дополнительную уверенность в том, что базы данных SQLite не будут повреждены неожиданными отключениями питания или сбросами устройств.

  • test_vfs.c - Этот файл реализует подключаемый модуль, который может использоваться для имитации сбоев файловой системы. Этот подключаемый модуль используется во время тестирования для проверки того, что SQLite адекватно реагирует на аппаратные неполадки или другие условия ошибок, такие как исчерпание места на файловой системе, которые сложно проверить на реальной системе.

Существуют и другие реализации VFS как в основном коде SQLite, так и в доступных расширениях. Приведённый выше список не является исчерпывающим, а лишь демонстрирует типы функций, которые можно реализовать с помощью интерфейса VFS.

4.Реализации VFS

Новая VFS реализуется путём наследования трёх объектов:

  • sqlite3_vfs
  • sqlite3_io_methods
  • sqlite3_file

Объект sqlite3_vfs определяет имя VFS и основные методы, которые реализуют интерфейс с операционной системой, такие как проверка существования файлов, удаление файлов, создание файлов, открытие и чтение/запись, преобразование имён файлов в их каноническую форму. Объект sqlite3_vfs также содержит методы для получения случайных данных от операционной системы, приостановки процесса (засыпания) и получения текущей даты и времени.

Объект sqlite3_file представляет собой открытый файл. Метод xOpen объекта sqlite3_vfs создаёт объект sqlite3_file, когда файл открывается. Объект sqlite3_file отслеживает состояние файла во время его открытия.

Объект sqlite3_io_methods содержит методы, используемые для взаимодействия с открытым файлом. Каждый объект sqlite3_file содержит указатель на объект sqlite3_io_methods, подходящий для представляемого им файла. Объект sqlite3_io_methods содержит методы для таких операций, как чтение и запись из файла, обрезка файла, сброс любых изменений в постоянное хранилище, определение размера файла, блокировка и разблокировка файла, закрытие файла и уничтожение объекта sqlite3_file.

Создание кода для новой VFS включает построение подкласса для объекта sqlite3_vfs и последующую регистрацию этого объекта VFS с помощью вызова sqlite3_vfs_register(). Реализация VFS также предоставляет подклассы для sqlite3_file и sqlite3_io_methods, но эти объекты не регистрируются напрямую в SQLite. Вместо этого объект sqlite3_file возвращается методом xOpen объекта sqlite3_vfs, и объект sqlite3_file указывает на экземпляр объекта sqlite3_io_methods.

Эта страница была в последний раз изменена 22 февраля 2024 г. в 15:53:45 UTC

SQLite is in the Public Domain.
https://sqlite.org/vfs.html

Spec-Zone.ru

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