SQLite совместим с блокировкой OpenAFS? - PullRequest
5 голосов
/ 29 марта 2011

Я хотел бы, чтобы многие процессы на многих сетевых компьютерах одновременно обращались к одной и той же базе данных SQLite через OpenAFS 1.4.12.1.Операции записи будут редкими, поэтому проект SQLite с одной записью не должен быть проблемой.

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

В документации SQLite говорится, что "SQLite использует консультативные блокировки POSIX для реализации блокировки в Unix".Он также предупреждает, что «Ваша лучшая защита - не использовать SQLite для файлов в сетевой файловой системе».Однако, похоже, не указывается, использует ли SQLite только блокировку всего файла или же он использует блокировку в диапазоне байтов.

У меня также возникают проблемы с поиском того, какие типы блокировок поддерживает OpenAFS 1.4.12.1.Этот неофициальный источник 1998 , к сожалению, лучший источник, который мне удалось найти.Тогда блокировка всего файла поддерживалась, но блокировка диапазона байтов не была.

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

РЕДАКТИРОВАТЬ: это вообще возможно?Если да, нужны ли какие-либо флаги SQLite во время компиляции?

1 Ответ

5 голосов
/ 04 апреля 2011

Я уже давно пользуюсь SQLite, и мне посчастливилось иметь дело с некоторыми проблемами с блокировками. Я вполне уверен, что SQLite по умолчанию использует блокировки байтового диапазона в файловых системах Unix.

Если быть более точным, он содержит код для нескольких альтернативных методов блокировки (например, с использованием flock() и стиля блокировки точек блокировки всего файла). При компиляции с параметром SQLITE_ENABLE_LOCKING_STYLE он пытается автоматически определить правильный метод блокировки для базовой файловой системы.

Код автоопределения содержит несколько жестко закодированных случаев (например, "ufs", "nfs" и "smbfs"), ни один из которых не является AFS. Если не найдено ни одного жестко заданного регистра, SQLite пытается получить блокировку диапазона байтов для файла, используя fcntl(). Затем предполагается, что если вызов fcntl() успешен, тогда доступны блокировки в байтовом диапазоне.

Здесь OpenAFS приходит, чтобы сделать вещи интересными . Очевидно ( [1] , [2] , [3] ) OpenAFS имеет длинную историю лжи приложениям пользовательского пространства о блокировки байтового диапазона. Из openafs-1.4.14 исходного кода:

/* next line makes byte range locks always succeed,
 * even when they should block */
if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
    DoLockWarning();
    afs_PutFakeStat(&fakestate);
    return 0;
}

Одним словом: Ой!

Это позволяет блокировкам байтового диапазона преуспеть, несмотря ни на что. В Linux это, возможно, еще хуже: он использует инфраструктуру ядра для обеспечения блокировок диапазона байтов среди процессов одной и той же системы . Это означает, что приложение не может просто разветвить новый процесс и протестировать механизм блокировки - блокировки в байтовом диапазоне будут работать нормально, но при этом не смогут защитить файл от удаленных процессов.

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

Несколько возможных обходных путей в произвольном порядке:

  • Используйте правильную СУБД, такую ​​как PostgreSQL . Если это возможно, в конечном итоге вам будет лучше.

  • Внедрите свой собственный сервер для своего приложения, если полноценная СУБД излишня.

  • Измените исходный код SQLite по умолчанию на flock() в OpenAFS. Я не уверен, что это будет работать должным образом, поскольку OpenAFS имеет долгую историю ( [1] , [2] ) проблем блокировки даже с простой старой flock(), но вы не узнаете, пока не протестируете его.

  • Реализуйте свою собственную VFS OpenAFS для SQLite, используя пользовательское пространство OpenAFS, а не проходя через ядро.

  • Испытайте удачу с другой сетевой файловой системой.

Что бы вы ни делали, вам придется проводить расширенное тестирование, если оно каким-либо образом связано с SQLite3 и файлом общей базы данных.

EDIT:

Комментатор предложил использовать механизм файлов точек блокировки. Я не слишком углублялся в исходный код OpenAFS, но на первый взгляд кажется, что он поддерживает метод open(O_CREAT|O_EXCL) для создания файлов точек блокировки, который использует SQLite. Если это работает так, как предполагалось, SQLite действительно может быть использован с OpenAFS, если вы заставите его использовать метод dotlock.

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

...