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

Small. Fast. Reliable.
Choose any three.

Powersafe Overwrite

"Powersafe overwrite" это термин, использованный командой SQLite, чтобы описать поведение некоторых файловых систем и дисковых контроллеров, связанных с сохранением данных во время потерь питания. Powersafe overwrite это булево свойство: у системы хранения оно есть или нет.

Мы говорим, что у системы есть powersafe overwrite, если следующее заявление верно:

Когда приложение напишет диапазон байтов в файле, никакие байты за пределами того диапазона не изменятся, даже если произойдет непосредственно перед сбоем или перебоем в питании.

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

Другими словами, powersafe overwrite значит, что нет никакого "сопутствующего ущерба", когда потери питания происходят при записи. Только те байты, которые на самом деле записаны, могли бы быть повреждены.

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

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

Предположения SQLite о Powersafe Overwrite

Все версии SQLite до и включая version 3.7.9 (2011-11-01) предполагают, что файловая система не обеспечивает powersafe overwrite. SQLite традиционно предположил, что, когда любой байт файла изменяется, у всех других байтов в том же самом секторе того байта есть потенциал того, чтобы быть испорченными при потере питания. Записывая, SQLite пишет в журнал все байты в том же самом секторе, где проводятся любые модификации, и это увеличивает файлы журнала к следующей границе сектора так, чтобы последующее дополнение журнала не могло повредить предшествующие записи. SQLite понимает размер сектора как значение, возвращенное методом xSectorSize в VFS. Команда SQLite часто упоминала значение, возвращенное методом xSectorSize, как "радиус поражения" записи, так как это выражает диапазон байтов, которые могли бы быть повреждены, если потеря питания происходит во время записи. VFSes по умолчанию для unix и windows всегда возвращали 512 как размер сектора (или радиус поражения) для всех версий SQLite до и включая version 3.7.9.

Более новые дисководы начали использовать 4096-байтовые сектора как бы то ни было. Начиная с SQLite version 3.7.10 (2012-01-16), группа разработчиков SQLite экспериментировала с изменениями xSectorSize, чтобы сообщить о 4096 байтах как радиус поражения. Это имело эффект увеличения издержек записи на многих базах данных. Для базы данных с PRAGMA page_size = 1024 (очень общий выбор) внесение изменения в единственную страницу в базе данных теперь требует, чтобы SQLite сделал копию трех других смежных страниц к журналу обратной перемотки, тогда как раньше это должно было сделать копию только одной страницы, которая изменялась. В режиме WAL каждая транзакция должна была быть увеличена к следующей 4096-байтовой границе в файле WAL, а не следующей 512-байтовой границе, приводя к тысячам дополнительных байтов, написанных за транзакцию.

Дополнительные издержки вызвали повторную проверку предположений о powersafe overwrite. С современными дисководами пропускная способность стала столь большой и плотность данных, настолько большая, что единственный сектор очень небольшой и запись единственного сектора занимает очень мало времени. Мы знаем, что дисководы могут обнаружить нависшие потери мощности и продолжить работать некоторое небольшое количество времени на остаточной энергии, потому что двигатели в состоянии припарковать их. И поэтому если нависшие потери мощности обнаружимы дисковым контроллером, кажется разумным, что диспетчер закончит писать безотносительно сектора, когда неизбежные потери мощности сначала обнаружены до парковки. Следовательно кажется разумным предположить powersafe overwrite для современных дисков. Действительно, BerkeleyDB делал это предположение в течение многих десятилетий, нам говорят. Осторожность рекомендуется все же. "Плохо написанное" должно быть главным предположением о встроенном микропрограммном обеспечении.

Порванные страницы

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

SQLite никогда не предполагает, что запись страницы базы данных атомная, независимо от PSOW.(1) Следовательно, SQLite всегда в состоянии автоматически прийти в себя после порванных страниц, вызванных катастрофой. Предоставление возможности PSOW не уменьшает способность SQLITE прийти в себя после порванной страницы.

Изменения в SQLite Version 3.7.10

VFS для SQLite version 3.7.10 (2012-01-16) добавляет новую характеристику устройства под названием 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 = on, хотя мы можем пересмотреть это в будущем и установить его в off.

powersafe overwrite для отдельных баз данных может быть определено, когда база данных открыта, используя параметр запроса "psow" с URI filename. Например, чтобы всегда принять powersafe overwrite для файла (возможно, чтобы гарантировать максимальную производительность записи), надо открыть его как

file:somefile.db?psow=1

Чтобы вынудить SQLite принять, что база данных точно без powersafe overwrite, надо указать

file:somefile.db?psow=0

Есть также новый код операции SQLITE_FCNTL_POWERSAFE_OVERWRITE для sqlite3_file_control(), который позволяет запросу получить значение свойства powersafe overwrite для файла базы данных.


Примечания:

  1. SQLite никогда не предполагает, что страница пишется атомно в конфигурациях по умолчанию. Но своя VFS может установить один из битов SQLITE_IOCAP_ATOMIC в результате метода xDeviceCharacteristic() и затем SQLite предположит, что запись страницы атомная. Применение должно поставлять свою VFS, чтобы достигнуть этого, так как ни одна из стандартных VFS никогда не будет устанавливать ни одного из атомных битов в векторе xDeviceCharacteristics().