RussianLDP Рейтинг@Mail.ru
WebMoney: 
WMZ Z294115950220 
WMR R409981405661 
WME E134003968233 
Visa 
4274 3200 2453 6495 

Small. Fast. Reliable.
Choose any three.
Контрольная сумма VFS

1. Обзор

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

Расширение контрольной суммы VFS требует версии SQLite version 3.32.0 (2020-05-22) или позже. Это не будет работать с более ранними версиями SQLite.

2. Компиляция

Модуль контрольной суммы VFS является загружаемым расширением. Это не включено в объединение. Это должно быть добавлено к SQLite во время компиляции или во время выполнения. Исходный код модуля контрольной суммы VFS находится в файле ext/misc/cksumvfs.c в исходном дереве SQLite.

Чтобы построить модуль VFS в загружаемое расширение времени выполнения, используйте команды, подобные следующим:

  • (linux) → gcc -fPIC -shared cksumvfs.c -o cksumvfs.so
  • (mac) → clang -fPIC -dynamiclib cksumvfs.c -o cksumvfs.dylib
  • (windows) → cl cksumvfs.c -link -dll -out:cksumvfs.dll

Можно добавить дополнительные параметры компилятора, конечно, согласно потребностям проекта.

Чтобы статически связать это расширение с вашим продуктом, соберите его как любой другой модуль языка C, но добавьте опцию "-DSQLITE_CKSUMVFS_STATIC", чтобы этот модуль знал, что это статически, а не динамично связывается.

3. Загрузка

Чтобы загрузить это расширение как общую библиотеку, сначала необходимо поднять фиктивное соединение с базой данных SQLite, чтобы использовать в качестве аргумента sqlite3_load_extension() API. Тогда вы вызываете sqlite3_load_extension() API и закрываете фиктивное соединение с базой данных. Все последующие соединения с базой данных, которые открыты, будут включать это расширение. Например:

sqlite3 *db;
sqlite3_open(":memory:", &db);
sqlite3_load_extension(db, "./cksumvfs");
sqlite3_close(db);

Если это расширение собрано с -DSQLITE_CKSUMVFS_STATIC и статически связано, инициализируйте его, используя единственный вызов API следующим образом:

sqlite3_cksumvfs_init();

Cksumvfs это прокладка VFS. Когда загружено, "cksmvfs" становится новой VFS по умолчанию и это использует предшествующую VFS по умолчанию в качестве следующей VFS вниз в стеке. Это обычно то, что вы хотите. Однако, в сложных ситуациях, где многократные прокладки VFS загружаются, могло бы быть важно гарантировать, что cksumvfs загружается в правильном порядке так, чтобы это упорядочило себя в стеке VFS по умолчанию в правильном порядке.

4. Использование

Откройте соединения с базой данных, используя sqlite3_open() или sqlite3_open_v2() как обычно. Обычные файлы базы данных (без контрольной суммы) будут работать как обычно. Базы данных с контрольными суммами возвратят ошибку SQLITE_IOERR_DATA, если столкнутся со страницей, которая содержит недействительную контрольную сумму.

Вычисление контрольной суммы работает только с базами данных, у которых есть резервные байты со значением точно 8. Значение по умолчанию для запасных байтов 0. Следовательно, недавно созданные файлы базы данных игнорируют контрольную сумму по умолчанию. Чтобы создать базу данных, которая включает контрольную сумму, измените значение резервных байтов на 8, управляя кодом, подобным этому:

int n = 8;
sqlite3_file_control(db, 0, SQLITE_FCNTL_RESERVE_BYTES, &n);

Если вы делаете это немедленно после создания нового файла базы данных, прежде чем что-либо еще было написано в файл, то это могло бы быть всем, что необходимо сделать. Иначе вызов API выше должен сопровождаться:

sqlite3_exec(db, "VACUUM", 0, 0, 0);

Никогда не повредит выполнить VACUUM, даже если он вам не нужен. Если база данных находится в режиме WAL, вы должны закрыть и вновь открыть все соединения с базой данных перед продолжением.

Из CLI используйте команду ".filectrl reserve_bytes 8" перед "VACUUM;".

Обратите внимание на то, что SQLite позволяет числу запасных байтов быть увеличенным, но не уменьшенным. Таким образом, если у файла базы данных уже есть значение запасных байтов, больше, чем 8, нет никакого способа активировать вычисление контрольной суммы на той базе данных, кроме дампа и восстаноления файла базы данных. Отметьте также, что другие расширения могли бы также использовать запасные байты. Вычисление контрольной суммы будет несовместимо с теми другими расширениями.

5. Проверка контрольных сумм

Если какая-либо контрольная сумма будет неправильной, то "PRAGMA quick_check" найдет ее. Чтобы проверить, что контрольные суммы на самом деле позволены и работают, используйте SQL:

SELECT count(*), verify_checksum(data) FROM sqlite_dbpage GROUP BY 2;

Есть три возможных вывода verify_checksum(): 1, 0 и NULL. 1 возвращен, если контрольная сумма правильна. 0 возвращен, если контрольная сумма неправильная. NULL возвращен, если страница нечитабельна. Если вычисление контрольной суммы будет позволено, чтение потерпит неудачу, если контрольная сумма будет неправильной, таким образом, обычным следствием verify_checksum() на неверной контрольной сумме является NULL.

Если все в порядке, запрос выше должен возвратить единственную строку, где вторая колонка равняется 1. Любой другой результат указывает что есть ошибка контрольной суммы или проверка контрольной суммы отключена.

6. Управление проверкой контрольной суммы

Расширение cksumvfs осуществляет новую команду PRAGMA, которая может использоваться, чтобы отключить, повторно включить или запросить статус проверки контрольной суммы:

PRAGMA checksum_verification;          -- query status
PRAGMA checksum_verification=OFF;      -- disable verification
PRAGMA checksum_verification=ON;       -- re-enable verification

"checksum_verification" pragma вернет "1" (true) или "0" (false), если проверка контрольной суммы будет позволена или отключена, соответственно. "Проверка" в этом контексте означает особенность, которая вызывает ошибки SQLITE_IOERR_DATA, если несоответствие контрольной суммы обнаружено, читая. Контрольные суммы всегда обновляются, пока значение резервных байт базы данных равняется 8, независимо от урегулирования этой pragma. Проверка контрольной суммы может быть отключена (например), чтобы сделать анализ базы данных, которая ранее сообщила об ошибке контрольной суммы.

"checksum_verification" pragma будет всегда отвечать "0", если у файла базы данных не будет резервных байт = 8. pragma не возвратит строк вообще, если расширение cksumvfs не будет загружено.