Small. Fast. Reliable.
Choose any three.
Интерфейс OS SQLite или "VFS"
Оглавление

1. Введение

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

2. VFS относительно остальной части SQLite

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

Эта статья о нижнем слое.

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

3. Много VFS

Стандартное исходное дерево SQLite содержит встроенные VFS для unix и windows. Альтернативный VFS может быть добавлен во время запуска или выполнения, используя sqlite3_vfs_register().

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

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

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

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

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

  3. unix-none все операции по блокировке файла не работают.

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

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

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

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

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

  2. win32-none все операции по блокировке файла не работают.

  3. win32-longpath-none комбинация "win32-longpath" и "win32-none".

Как в unix, разделяется большая часть кода для Windows VFS.

3.3. Определение, который VFS использовать

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

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

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

Дополнительный VFS может также быть определен как 4-й параметр 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 по умолчанию используется, если никакой VFS не определяется иначе.

3.4. VFS Shims

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

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

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

Следующее это другие внедрения VFS, доступные в общественном исходном дереве SQLite:

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

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

Новый VFS осуществляется, подклассифицируя три объекта:

Объект 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.