Насколько безопасен SQLite WAL при сбоях питания? - PullRequest
5 голосов
/ 27 августа 2010

В документации SQLite о функции записи в журнал, представленной в версии 3.7, есть некоторые комментарии, которые меня немного смутили.

На связанной странице написано, что «синхронизация содержимого на диске не требуется, если приложение готово пожертвовать долговечностью после потери питания». Затем в нескольких параграфах говорится: «Контрольная точка требует операций синхронизации, чтобы избежать возможности повреждения базы данных после потери питания или полной перезагрузки» ».

Так что, если я использую WAL, моя база данных подвергается большему риску повреждения из-за потери питания?

Ответы [ 3 ]

5 голосов
/ 03 февраля 2012

Чтобы ответить полностью, нам нужно знать, на что установлена ​​PRAGMA synchronous, поскольку это влияет на то, когда вызывается fdatasync() и, следовательно, когда на физическом диске сбрасываются буферы.

Когда вы цитируете «пока приложение готово пожертвовать долговечностью после потери питания», это означает наличие synchronous=NORMAL. Здесь WAL синхронизируется только с диском, когда происходит контрольная точка (одна fdatasync() для WAL и одна для основной БД после ее объединения). Вы должны быть защищены от коррупции довольно хорошо, но могут быть некоторые записи, которые так и не попали на блюдо и, таким образом, потерялись: отсюда и потеря прочности. Тем не менее, положительный эффект от медленной функции fdatasync () для синхронизации данных намного меньше.

Чтобы обеспечить наилучшую устойчивость к потере данных, вам может потребоваться synchronous=FULL. Это восстанавливает долговечность, но стоимость составляет одну fdatasync() за транзакцию записи. Однако это все же лучше, чем в режиме без WAL, когда будет два fdatasync() вызова - один для журнала транзакций и один для основной БД.

4 голосов
/ 27 августа 2010

Нет повышенного риска повреждения с WAL (так как он использует операции синхронизации при проверке точек).

Однако, если произойдет сбой (потеря питания или полная перезагрузка), вы потеряете все транзакции со времени последней контрольной точки; это то, что подразумевается под «жертвой долговечности».

0 голосов
/ 20 марта 2012

До тех пор, пока синхронные вызовы в вашей ОС работают идеально, вы рискуете испортить БД. Однако, это может или не может иметь место - см. Документацию sqlite для более подробного объяснения этого.

Чтобы исправить Дуга Керри (см. Статью MattR): Вы рискуете потерять транзакции только если @ synchronous = NORMAL @. Если @ synchronous = FULL @ (по умолчанию), вы не жертвуете долговечностью. Подробнее см. http://www.sqlite.org/draft/wal.html.

Я считаю, что ведение журнала WAL на самом деле безопаснее, чем «классическое» ведение журнала (в случае несовершенной синхронизации системы), потому что вероятность того, что БД сделает что-то критическое в данный момент, ниже, насколько я понимаю, ведение журнала WAL. Однако в настоящее время у меня нет точных данных, подтверждающих это.

...