Статьи Новости Контакты
MySQL (0)

20.03.2008
Даниил Буров

SQLite: «атомная» транзакция

описание принципов работы SQLite

Заглавная иллюстрация

Важной характеристикой работоспособности для такой базы данных, как SQLite, является atomic commit, что можно перевести как "целостная транзакция". Данный термин означает, что либо вся база данных производит изменение за одну транзакцию, либо она не делает этого вообще. В процессе целостной транзакции производится множество различных записей в разные секции файла базы данных — мгновенно и одновременно. Реальные аппаратные средства последовательно преобразовывают записи в запоминающем устройстве повышенной емкости, и записывание одного сектора занимает конечный отрезок времени. Таким образом, выходит, что невозможно действительно записать множество секторов в файле базы данных одновременно и/или мгновенно. Однако логика целостной транзакции в SQLite позволяет говорить о возможности подобного процесса, когда изменения в файле БД происходят в одно время и практически мгновенно.

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

Аппаратные предположения

Рассматриваемый вопрос довольно объемен. Чтобы лучше понять суть данного процесса, придется перечислить множество условий, выдвигаемых разработчиками SQLite. Например, для простоты понимания по ходу описания все запоминающие устройства большой емкости будут называться "диском", даже при том, что данное устройство может оказаться простой флеш-памятью. Также предполагается, что диск состоит из "частей", которые здесь будут называться секторами. Это означает, что будет невозможно изменить часть диска, меньшую, чем сектор. Чтобы изменить часть диска, которая меньше сектора, необходимо сначала прочитать весь сектор, содержащий нужную для изменения часть, произвести изменение, а потом перезаписать весь сектор.

На традиционных дисках вращения сектор является минимальным модулем, работающим в двух направлениях — на чтение и запись. При этом во флеш-памяти минимальный размер читаемой памяти значительно меньше, чем минимально записываемой. Для SQLite более приоритетным является размер записываемого участка, потому в статье, когда будет говориться о "секторе", будет подразумеваться минимальное количество данных, которое может быть записано на запоминающее устройство за один заход.

Разработчики SQLite утверждают, что на данный момент не существует стандартного метода для обнаружения истинного размера сектора ни на Win32, ни на Unix
До SQLite версии 3.3.14 во всех случаях был принят размер сектора, равный 512 байтам. Была опция, позволявшая во время компиляции изменять этот размер, но код никогда еще не тестировался с большим значением. Использование 512-байтных секторов казалось разумным до тех пор, пока все дисководы сами их использовали. Однако не так давно произошел толчок к увеличению размера дисковых секторов 4096 байт. К тому же размер сектора для флеш-памяти обычно также был больше 512 байт. По этим причинам, начиная с версии SQLite 3.3.14, обладают методом на уровне интерфейса операционной системы, который опрашивает основную файловую систему, чтобы выяснить истинный размер сектора. Этот метод работает и в настоящее время, все еще возвращая жестко кодированное значение 512 байт. Поэтому не существует стандартного пути обнаружения истинного размера сектора ни на Win32, ни на Unix. Тем не менее метод можно применять для производства внедренных устройств — для обеспечения их потребностей. Потому разработчики оставили возможность для использования в будущем своих наработок в более важных проектах на Win32 и Unix.

SQLite не предполагает, что запись сектора является целостной. Однако предусматривает, что она является линейной. Под термином "линейная запись" разработчики подразумевают, что SQLite предполагает, что при записи сектора аппаратные средства начинают от конца одних данных и пишут байт за байтом, пока не достигнут другого конца. Запись может идти от начала до конца или от конца к началу. Если же во время записи сектора происходит сбой питания, то это может означать, что часть сектора была изменена, а другая часть осталась без изменения. Ключевое предположение SQLite в том, что если часть сектора была изменена, то в нем будут также изменены или первые, или последние байты. А аппаратные средства никогда не начнут запись сектора с середины и до конца. Разработчики SQLite не утверждают, что так всегда происходит, но, на их взгляд, такое утверждение кажется разумным.

В предыдущем параграфе утверждается: SQLite не предполагает, что сектор записывается мгновенно и целиком. Это правильно по умолчанию. Однако, начиная с SQLite версии 3.5.0, библиотека располагает новым интерфейсом, который называется "интерфейс виртуальной файловой системы" (Virtual File System). Виртуальная файловая система является единственным средством, с помощью которого SQLite связывается с основной файловой системой. Код, входящий в основу VFS по умолчанию, выполнен для работы с Unix и Windows. Также существует механизм для создания новой VFS по выбору в процессе работы. В интерфейсе этой новой VFS используется метод, называемый xDeviceCharacteristics. Этот метод опрашивает основную файловую систему на предмет обнаружения различных свойств и режимов, которые она показывает либо нет. Метод xDeviceCharacteristics может показать, какие секторы могут записываться целостно, показывать, если это не так, а SQLite попытается использовать этот факт в своих интересах. Однако по умолчанию этот метод не указывает целостность записи секторов сразу для обеих — Unix и Windows, потому такие оптимизации обычно опускаются.

Использование метода xDeviceCharacteristics позволяет ускорить работу SQLite
SQLite допускает, что операционная система буферизует записи, и эти записанные запросы возвращаются прежде, чем данные будут фактически сохранены на запоминающем устройстве. Далее SQLite предполагает, что операции записи будут переупорядочены операционной системой. По этой причине SQLite в ключевых точках совершает операцию flush или fsync. SQLite считает, что данные операции не вернутся, пока не закончатся все ждущие обработки операции для файлов, сброшенных на диск. Разработчикам было сказано, что операции flush и fsync не работают на некоторых версиях Windows и Linux. И это весьма досадно, так как открывает возможность SQLite для искажения базы данных вследствие сбоя питания на середине передачи. В таком случае SQLite не сможет ничего сделать для тестирования или исправления ситуации. Разработчики с оттенком иронии предполагают, что операционная система работает так же хорошо, как и рекламируется. Если же это не так, то они надеются, что отключения питания не будут происходить слишком часто на ПК пользователей.

Еще одна оговорка: SQLite предполагает, что, когда файлы разрастаются в объеме, пространство диска первоначально состоит из мусора, а позже оно становится фактически полностью записанным. Другими словами, SQLite допускает, что размер файлов изменяется раньше, чем их содержимое. Это довольно-таки пессимистическое предположение, потому разработчики провели отдельное исследование, чтобы удостовериться, что это не вызывает искажение базы данных при сбое питания между моментами, когда размер файла вырос и когда записано новое содержимое. Метод xDeviceCharacteristics виртуальной файловой системы мог бы указать, что файловая система будет всегда записывать данные перед изменением размера файла. Эта опция в настройках называется SQLITE_IOCAP_SAFE_APPEND. Когда метод xDeviceCharacteristics показывает, что содержимое файла записано до изменения его размера, SQLite может воздержаться от некоторых педантичных шагов базы данных, направленных на защиту, и тем самым уменьшить количество обращений к диску, необходимых для выполнения передачи. Однако текущее выполнение не делает подобных допущений для VFS, идущей по умолчанию для Windows и Unix.

SQLite предполагает, что удаление файлов является целостным с точки зрения пользовательского процесса. Под этим разработчики подразумевают, что при сбое питания во время удаления файла, как только энергоснабжение восстановится, файл либо будет существовать полностью — со всем первоначальным содержимым, — либо он вообще не будет виден в файловой системе. Если после восстановления питания файл будет лишь частично удален и только некоторые из его данных будут удалены или стерты либо файл будет урезан, но не удален полностью, тогда вероятным исходом будет искажение БД.

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

Промежуточный итог

Разработчики SQLite оговаривают множество пунктов, прежде чем перейти к основным принципам реализации своего механизма "атомной передачи". Основными составляющими целостной транзакции, введенными ими в этой части, являются понятие неделимости сектора диска, линейность процесса его записи, а также наличие конечного отрезка времени, за который происходит этот процесс. Используемый в SQLite метод, называемый разработчиками xDeviceCharacteristics, позволяет (при его применении) упростить обработку файлов, сократив количество запросов базы данных к диску, а значит, увеличить скорость работы БД. С момента выхода SQLite версии 3.5.0 библиотека располагает интерфейсом виртуальной файловой системы (Virtual File System). Виртуальная файловая система является тем средством, с помощью которого SQLite связывается с основной файловой системой и подстраивается под нее. Реализация в SQLite механизма целостной транзакции будет подробно рассмотрена в следующей статье.





Скоро на сайте

  • Wordpress

    Серия статей о плагинах к движку WordPrress
  • AJAX

    Проекты и продукты, ориентированные на AJAX
  • Новые сервисы Google

    Обзор новых сервисов Google
 

Copyright © 2003—2018 Все права защищены

При использовании материалов сайта ссылка на hostinfo.ru обязательна

  • хостинг от .masterhost
  • Rambler's Top100