description |
---|
## Как обеспечивается: |
- согласованность
- атомарность
- целостность
В файловой при записи данных файла сохраняет: метаданные и сами байты в память ( буферизация данных) и только потом сбрасывает на диск.
Даже, если мы записываем 4 байта, в память будет загружено - 4кб страницу)
- журналирование данных ( WAL ( like Postgres, Kafka + номер версии, корректности данных ( валидации, старые или новые, соответствие метаданных и байтов )
- использование паттернов, для целостности данных (
ARVR
(Atomic Replace Via Rename) - атомарное обновление содержимого существующего файла через его переименование не всеми гарантируется - при замене старого файла на новый, в файле может оказаться только часть данныхACVR
(Atomic Create Via Rename) - атомарное создание нового файла через переименование никем не гарантируется - при переименовании временного файла, новый может не содержать всех данных и быть нулевой длины)
- сегментация и снапшот ( Postgres - wal сегментированный, что позволяет увеличить скорость потоковой репликации, ускорить чтение и восстановление данных, увеличивается скорость записи в WAL )
Undo лог хранит в себе данные, которые необходимы для отката операций. В случае перезаписи файла, он хранит в себе участки исходного файла, которые мы перезаписываем. Например, если мы хотим записать новые данные (new_data
) начиная с 10 байта (start
) длиной в 15 байтов (length
), то в этот лог будут записаны байты с 10 по 15 из текущего, еще не измененного файла (old_data
). Алгоритм записи данных будет следующим:
creat("/dir/undo.log")
- Создаем файл undo логаwrite("/dir/undo.log", "[check_sum, start, length, old_data]")
- Записываем в него данные из исходного файла, которые собираемся изменить:start
- позиция, с которой собираемся производить записьlength
- длина перезаписываемого участкаold_data
- данные исходного файла, которые перезаписываем (не новые, а старые для отката)check_sum
- чек-сумма, вычисленная дляstart
,length
иold_data
fsync("/dir/undo.log")
- Сбрасываем данные файла на дискfsync("/dir")
- Сбрасываем содержимое директории (теперь undo лог точно на диске)write("/dir/data", new_data)
- Записываем новые данныеfsync("/dir/data")
- Сбрасываем изменения основного файла на дискunlink("/dir/undo.log")
- Удаляем undo логfsync("/dir")
- Сбрасываем изменение данных директории на диск (удаление undo лога)
- Отказ прямо после создания файла undo лога - в начале идет чек-сумма, с помощью которой можно это обнаружить
- Переупорядочивание операций записи - чек-сумма для всей записи в undo логе на случай, если операции будут переупорядочены (если изменения большие, то возможно одним
write
не обойтись) или нарушена целостность - Отказ перед началом записи данных в сам файл - вызываем
fsync
для файла undo лога и его директории (файл лога точно на диске) - Удаление самого файла undo лога - в конце вызываем
fsync
для директории, чтобы undo лог был действительно удален