Powersafe Overwrite
"Powersafe overwrite" — это термин, используемый командой SQLite для описания поведения некоторых файловых систем и контроллеров дисков, связанного с сохранением данных при отключении питания. Powersafe overwrite — это булево свойство: либо система хранения его имеет, либо нет.
Мы говорим, что система обладает свойством powersafe overwrite, если следующее утверждение истинно:
When an application writes a range of bytes in a file, no bytes outside of that range will change, even if the write occurs just before a crash or power failure.
Свойство powersafe overwrite ничего не говорит о состоянии записанных байтов. Эти байты могут содержать свои старые значения, новые значения, случайные значения или некоторую комбинацию этих значений. Свойство powersafe overwrite лишь утверждает, что запись не может изменить байты за пределами диапазона записанных байтов.
Другими словами, powersafe overwrite означает, что при отключении питания во время записи не происходит «побочного ущерба». Повреждаться могут только те байты, которые фактически записываются.
В практическом плане свойство powersafe write означает, что когда контроллер диска обнаруживает приближающееся отключение питания, он завершает запись того сектора, над которым работает, прежде чем убрать головки. Это означает, что отдельные сектора будут записаны полностью, как только процесс записи начнется, даже если произойдет отключение питания.
Представьте, что запись сектора диска прерывается отключением питания. Если приложение записывает два или три байта посредине файла, операционная система выполнит это, сначала прочитав весь сектор, содержащий эти байты, внеся изменения в сектор в памяти, а затем записав весь сектор обратно на диск. Если при записи произойдет отключение питания, и сектор не был полностью записан, то при следующем чтении после перезагрузки коды коррекции ошибок в секторе, вероятно, обнаружат невосполнимые повреждения, и контроллер диска прочитает сектор как все нули или все единицы. Таким образом, значения изменятся за пределами диапазона двух или трех байтов, которые были записаны на уровне приложения — нарушение свойства powersafe overwrite.
Предположения SQLite о Powersafe Overwrite
Все версии SQLite до и включая версию 3.7.9 (01.11.2011) предполагают, что файловая система не предоставляет powersafe overwrite. SQLite традиционно предполагал, что при изменении одного байта файла все остальные байты в том же секторе этого байта могут быть повреждены при отключении питания. При записи SQLite убеждался в том, чтобы журналировать все байты в том же секторе любых изменений, и он дополнял файлы журнала до границы следующего сектора, чтобы последующие добавления в этот журнал не могли повредить предыдущие записи. SQLite понимает размер сектора как значение, возвращаемое методом xSectorSize в VFS. Команда SQLite часто называла значение, возвращаемое xSectorSize, «радиусом взрыва» записи, так как оно выражает диапазон байтов, которые могут быть повреждены при отключении питания во время записи. Стандартные VFS для Unix и Windows всегда возвращали 512 как размер сектора (или радиус взрыва) для всех версий SQLite до и включая версию 3.7.9.
Однако более новые накопители начали использовать сектора размером 4096 байтов. Начиная с SQLite версии 3.7.10 (16.01.2012), команда разработчиков SQLite экспериментировала с изменениями xSectorSize, чтобы сообщить о размере взрыва в 4096 байтов. Это привело к увеличению накладных расходов на запись во многих базах данных. Для базы данных с PRAGMA page_size размером 1024 (очень распространенный выбор), изменение одной страницы в базе данных теперь требует от SQLite резервной копии трех других смежных страниц в журнале отката, тогда как раньше он должен был создавать резервную копию только одной изменяющейся страницы. В режиме WAL каждая транзакция должна была быть дополнена до следующей границы в 4096 байтов в файле WAL, а не до следующей границы в 512 байтов, что приводило к записи тысяч дополнительных байтов за каждую транзакцию.
Дополнительные накладные расходы на запись побудили пересмотреть предположения о powersafe overwrite. В современных накопителях емкость стала настолько большой, а плотность данных настолько высокой, что один сектор очень мал, а запись одного сектора занимает очень мало времени. Мы знаем, что накопители могут обнаруживать приближающееся отключение питания и продолжать работу в течение некоторого небольшого времени за счет остаточной энергии, так как эти накопители могут убрать головки перед остановкой вращения. Итак, если контроллер диска может обнаружить приближающееся отключение питания, кажется разумным, что он завершит запись текущего сектора, как только будет обнаружено приближающееся отключение питания, перед убиранием головок, если это не займет слишком много времени, чего, вероятно, не будет с небольшими и плотно упакованными секторами. Поэтому кажется разумным предположить powersafe overwrite для современных дисков. Действительно, BerkeleyDB сделала это предположение на протяжении десятилетий, как нам сказали. Однако следует проявлять осторожность. Как отметил Роджер Биннс на форуме разработчиков SQLite: «"плохо написанный" должен быть основным предположением относительно прошивки накопителя".
Разрывы страниц
Разрыв страницы происходит, когда страница базы данных больше размера сектора диска, страница базы данных записывается на диск, но происходит отключение питания до записи всех секторов страницы базы данных. Затем при восстановлении часть страницы базы данных будет содержать старое содержимое, а некоторые другие части страницы — новое содержимое. Некоторые движки баз данных предполагают, что записи страниц являются атомарными, и поэтому разрыв страницы является невосстанавливаемой ошибкой.
SQLite никогда не предполагает, что записи страниц базы данных являются атомарными, независимо от настройки PSOW.(1) Поэтому SQLite всегда может автоматически восстанавливаться от разрывов страниц, вызванных сбоем. Включение PSOW не уменьшает способность SQLite восстанавливаться от разрыва страницы.
Изменения в версии SQLite 3.7.10
VFS для SQLite версии 3.7.10 (16.01.2012) добавляет новую характеристику устройства под названием SQLITE_IOCAP_POWERSAFE_OVERWRITE. Предполагается, что файлы баз данных, которые сообщают об этой характеристике, находятся на системах хранения, которые обладают свойством powersafe overwrite. Стандартные VFS для Unix и Windows теперь сообщают о SQLITE_IOCAP_POWERSAFE_OVERWRITE, если SQLite скомпилирован с -DSQLITE_POWERSAFE_OVERWRITE=1, или же они используют старое предположение, что хранилище не имеет свойства powersafe overwrite, если скомпилировано с -DSQLITE_POWERSAFE_OVERWRITE=0. Пока по умолчанию powersafe overwrite включен, но мы можем пересмотреть это в будущем и установить по умолчанию выключение.
Свойство powersafe overwrite для отдельных баз данных можно указать при открытии базы данных с использованием параметра запроса «psow» в URI имени файла. Например, чтобы всегда предполагать powersafe overwrite для файла (возможно, для обеспечения максимальной производительности записи), откройте его как
file:somefile.db?psow=1
Или для дополнительной безопасности базы данных и для принудительного предположения SQLite, что база данных не имеет powersafe overwrite, откройте ее с помощью
file:somefile.db?psow=0
Также существует новый оператор SQLITE_FCNTL_POWERSAFE_OVERWRITE для sqlite3_file_control(), который позволяет приложению запросить свойство powersafe overwrite для файла базы данных.
Примечания:
SQLite никогда не предполагает атомарных записей страниц в своих стандартных конфигурациях. Но настраиваемый VFS может установить один из битов SQLITE_IOCAP_ATOMIC в результате метода xDeviceCharacteristic(), а затем SQLite предположит, что записи страниц являются атомарными. Однако приложение должно предоставить настраиваемый VFS для этого, так как ни один из стандартных VFS никогда не будет устанавливать какие-либо атомарные биты в вектор xDeviceCharacteristics().
Эта страница была последняя изменена 08.01.2022 05:02:57 UTC
SQLite is in the Public Domain.
https://sqlite.org/psow.html