Re[5]: Транзакционная прокладка для файловой системы
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.12.21 13:44
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, samius, Вы писали:


S>>На практике же слишком легко получить рассогласованные данные в файле, даже записывая данные в цикле постранично с flush-ами. При краше легко обнаружить несколько страниц рассогласованных данных даже на модном SSD.


vsb>fsync предоставляет все нужные гарантии.

Конкретно с fsync-ом я не работал. Настаивать не буду. Но в любом случае гарантии fsync-а опираются на репорт устройства, которое может халтурить в угоду производительности.
flushfilebuffers таких гарантий не дает, но и не обеспечивает. Т.е. кнопка ресет радует нас несколькими страницами битых записей. Страницей я тут называю данные, записанные между flushfilebuffers в цикле.

С другой стороны, полное обеспечение гарантий fsync обеспечит заметной деградацией производительности.
Re[7]: Транзакционная прокладка для файловой системы
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.12.21 13:45
Оценка:
Здравствуйте, Sharov, Вы писали:
S>>SetLength. Нам придётся при его выполнении сохранять в лог весь отрезаемый хвост или добавляемые нули.
S>А зачем лог для этого трогать? Почему просто не указывать новую длину файла, без данных?
Потому что сбой может произойти в любой момент. А нам надо уметь восстановить данные так, чтобы они включали всё из закоммиченных транзакций, и ничего из незакоммиченных.
К примеру, если мы урезали файл, то есть риск, что это изменение уже сохранилось на диск. А потом у нас сбой — но транзакция ещё не завершена. Мы должны суметь вернуть обратно не только длину, но и все выброшенные данные.
С нулями не так очевидно — может быть, можно и не писать их в лог в явном виде, а обойтись сокращённой записью — типа "отсюда и досюда будут нули".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Транзакционная прокладка для файловой системы
От: vsb Казахстан  
Дата: 28.12.21 14:46
Оценка:
Здравствуйте, samius, Вы писали:

vsb>>fsync предоставляет все нужные гарантии.

S>Конкретно с fsync-ом я не работал. Настаивать не буду. Но в любом случае гарантии fsync-а опираются на репорт устройства, которое может халтурить в угоду производительности.

Такое устройство можно смело считать неисправным. Никакой софт на нём не даст гарантий. Это из разряда китайских флешек, которые пишут данные в кольцевой буфер — записать на них можно много, только со считыванием проблемы будут.

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


Не совсем понимаю, зачем использовать эту функцию.

S>С другой стороны, полное обеспечение гарантий fsync обеспечит заметной деградацией производительности.


fsync не нужно использовать на каждый чих и не будет деградации.
Re[7]: Транзакционная прокладка для файловой системы
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.12.21 14:59
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, samius, Вы писали:


S>>Конкретно с fsync-ом я не работал. Настаивать не буду. Но в любом случае гарантии fsync-а опираются на репорт устройства, которое может халтурить в угоду производительности.


vsb>Такое устройство можно смело считать неисправным. Никакой софт на нём не даст гарантий. Это из разряда китайских флешек, которые пишут данные в кольцевой буфер — записать на них можно много, только со считыванием проблемы будут.


Считать-то можно. Кто вернет за него деньги?

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


vsb>Не совсем понимаю, зачем использовать эту функцию.

Затем, что fsync на винде нет и flushfilebuffers является ближайшим аналогом.

S>>С другой стороны, полное обеспечение гарантий fsync обеспечит заметной деградацией производительности.


vsb>fsync не нужно использовать на каждый чих и не будет деградации.

Разумеется. Можно было написать "не нужно использовать транзакции на каждый чих".
Re[5]: Транзакционная прокладка для файловой системы
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.12.21 17:55
Оценка: 31 (2)
Здравствуйте, vsb, Вы писали:

vsb>fsync предоставляет все нужные гарантии.

Угу. PostgreSQL used fsync incorrectly for 20 years.
Даже если мы ограничимся только платформами, в которых есть fsync (а не FlushFileBuffers). Плюс там есть ещё нюансы, ЕМНИП, про разницу в fsync в разных ФС.
Если тупая железка не пытается хитрить ещё дальше.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: Транзакционная прокладка для файловой системы
От: Sinclair Россия https://github.com/evilguest/
Дата: 28.12.21 17:58
Оценка:
Здравствуйте, samius, Вы писали:
S>Затем, что fsync на винде нет и flushfilebuffers является ближайшим аналогом.
S>>>С другой стороны, полное обеспечение гарантий fsync обеспечит заметной деградацией производительности.
Сами собаководы для сценариев типа WAL рекомендуют вместо FlushFileBuffers таки использовать FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH. Как раз чтобы избежать ещё большей просадки производительности.

vsb>>fsync не нужно использовать на каждый чих и не будет деградации.

S>Разумеется. Можно было написать "не нужно использовать транзакции на каждый чих".
+1
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[9]: Транзакционная прокладка для файловой системы
От: samius Япония http://sams-tricks.blogspot.com
Дата: 28.12.21 18:36
Оценка: 45 (2)
Здравствуйте, Sinclair, Вы писали:

S>Сами собаководы для сценариев типа WAL рекомендуют вместо FlushFileBuffers таки использовать FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH. Как раз чтобы избежать ещё большей просадки производительности.


Там слишком много магии с выравниванием буфера и в контексте донтета оно выглядит нетривиально реализуемым, как минимум.

As previously discussed, an application must meet certain requirements when working with files opened with FILE_FLAG_NO_BUFFERING. The following specifics apply:

File access sizes, including the optional file offset in the OVERLAPPED structure, if specified, must be for a number of bytes that is an integer multiple of the volume sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1,024, 1,536, or 2,048 bytes, but not of 335, 981, or 7,171 bytes.
File access buffer addresses for read and write operations should be physical sector-aligned, which means aligned on addresses in memory that are integer multiples of the volume's physical sector size. Depending on the disk, this requirement may not be enforced.

https://docs.microsoft.com/en-us/windows/win32/fileio/file-buffering

Да и все, что может сделать винда — это передать буфер в драйвер файловой системы. Остальное остается на откуп драйера устройства и самого устройства со своим маркетингом, направленным на скорость работы, а не на гарантии при отключении питания.

Note Not all hard disk hardware supports this write-through capability.

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea#caching_behavior

Так, если девайс не поддерживает write-through, то и fsync пролетает точно так же. Об чем и речь.
Re: Транзакционная прокладка для файловой системы
От: VladD2 Российская Империя www.nemerle.org
Дата: 28.12.21 23:58
Оценка:
Здравствуйте, Barbar1an, Вы писали:

B>задача скучная: нужно чтобы при падении процесса, файлы оставались в последнем корректном состоянии

B>в общем нужны транзакции

Ну, храни бэкап-копии до выхода, а при выходе проверяешь консистентность и из одного потока переименовываешь.

Как вариант, сам организуй журналирование с момента последней копии и восстановление путем накатывания журналов после падения. Уж сессионные транзакции это не особая проблема.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Транзакционная прокладка для файловой системы
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.12.21 00:08
Оценка: 14 (1)
Здравствуйте, Barbar1an, Вы писали:

B>остается шанс что файлы поменяли, а метка не успела записаться


Так не надо рассчитывать на то, что файл поменян. Надо иметь железобетонную копию от которой писать лог. И при сбое раскручивать лог с этой железобетонной копии. А текущую копию (ломанную) в помоечку отправлять. Примерно так инкрементальные бэкапы работают. Убедиться, что все данные сброшены на "диск" таки можно. При корректном выходе (что будет 99.99% времени) проверяешь лог, принимаешь старый файл за железобетонную копию и начинаешь писать лог от нее. При некорректном — восстанавливаешься с прошлой версии по логам. Какая-то часть логов да запишется. После восстановления у тебя появится новая железобетонная копия и можно будет писать новый лог.

Но действительно, лучше взять готовую СУБД. Может в скорости не выиграешь, данные целей будут, так как мелкий баг в твоем коде не угробит все данные за 10 лет.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: Транзакционная прокладка для файловой системы
От: Teolog  
Дата: 29.12.21 09:32
Оценка:
S>По принципу git? Вот и ответ, но он не быстр.

Не годиться, git репозитории мрут только так при повреждении индекса
Re: Транзакционная прокладка для файловой системы
От: Teolog  
Дата: 29.12.21 09:40
Оценка:
Поделить базу на блоки, при записи создавать новую копию блока, можно отдельным файлом, потом перенацеливать индекс со старого блока на новый.
Держать все на ssd c raid.
Re[5]: Транзакционная прокладка для файловой системы
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.12.21 11:16
Оценка:
Здравствуйте, Teolog, Вы писали:


S>>По принципу git? Вот и ответ, но он не быстр.


T>Не годиться, git репозитории мрут только так при повреждении индекса

Я под принципом git подразумевал саму идею Commit history, но не конкретное исполнение с двоичный файлом, не годящимся для инкрементального пополнения.
Re[2]: Транзакционная прокладка для файловой системы
От: Sinclair Россия https://github.com/evilguest/
Дата: 29.12.21 13:00
Оценка:
Здравствуйте, Teolog, Вы писали:

T>Поделить базу на блоки, при записи создавать новую копию блока, можно отдельным файлом, потом перенацеливать индекс со старого блока на новый.

Для этого надо уметь гарантировать ордеринг операций с разными файлами
Иначе после сбоя окажется, что индекс уже перенаправлен, а новая копия блока ещё не создалась.
T>Держать все на ssd c raid.\
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Транзакционная прокладка для файловой системы
От: Teolog  
Дата: 29.12.21 14:25
Оценка: :)
S>Для этого надо уметь гарантировать ордеринг операций с разными файлами
S>Иначе после сбоя окажется, что индекс уже перенаправлен, а новая копия блока ещё не создалась.

Не надо, у топик стартера проблема в обеспечении консистентности при падении программы в любой момент, а не обеспечении консистентности при любых мыслимых сбоях включая ядерный взрыв.
Более простая и разрешимая задача. Думаю он сейчас опадает в осадок от глубины на которую некоторые копают.
Re[6]: Транзакционная прокладка для файловой системы
От: Sharov Россия  
Дата: 29.12.21 15:10
Оценка:
Здравствуйте, samius, Вы писали:

T>>Не годиться, git репозитории мрут только так при повреждении индекса

S>Я под принципом git подразумевал саму идею Commit history, но не конкретное исполнение с двоичный файлом, не годящимся для инкрементального пополнения.

А чем commit history от лога db отличается?
Кодом людям нужно помогать!
Re[8]: Транзакционная прокладка для файловой системы
От: Sharov Россия  
Дата: 29.12.21 15:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>>А зачем лог для этого трогать? Почему просто не указывать новую длину файла, без данных?

S>Потому что сбой может произойти в любой момент. А нам надо уметь восстановить данные так, чтобы они включали всё из закоммиченных транзакций, и ничего из незакоммиченных.
S>К примеру, если мы урезали файл, то есть риск, что это изменение уже сохранилось на диск. А потом у нас сбой — но транзакция ещё не завершена. Мы должны суметь вернуть обратно не только длину, но и все выброшенные данные.

Так все операции после записи в лог. Сбой тут как помешает, если перед этим залогировались?

S>С нулями не так очевидно — может быть, можно и не писать их в лог в явном виде, а обойтись сокращённой записью — типа "отсюда и досюда будут нули".


Setlength можно отельной записью в логе оформить и все.
Кодом людям нужно помогать!
Re[7]: Транзакционная прокладка для файловой системы
От: samius Япония http://sams-tricks.blogspot.com
Дата: 29.12.21 18:19
Оценка: 10 (1) +1
Здравствуйте, Sharov, Вы писали:

S>А чем commit history от лога db отличается?

Commit history — это журнал принятых изменений, дельт*, а лог базы — более сложная вещь, которая может содержать как сами изменения (дельты), так и компенсирующие записи для откатов (дельты наоборот), записи о начале, завершении, отмене транзакций, чекпоинты в некоторых случаях, и т.п.

(*) конкретно в git commit history сохраняет версии файлов, а дельты строит для близких по размеру версий файлов во время GC или при отправке по сети. Ну да в целом — похоже, если git- объекты считать чекпоинтами, а pack-файлы прямыми и обратными дельтами.

Ключевое отличие, пожалуй, в том, что Commit history не содержит промежуточных данных между коммитами, а лог db — история изменений каждой строки, т.е. изменения могут проигрываться и откатываться даже внутри транзакции.

С такой точки зрения журнализация операций над FileStream будет все-таки ближе к логу db, чем к commit history.
Re[5]: Транзакционная прокладка для файловой системы
От: Mystic Artifact  
Дата: 29.12.21 18:40
Оценка: +1
Здравствуйте, VladD2, Вы писали:

Современные MSSQL умеют восстанавливаться и быстрее и имеют меньший размер журнала. Он активно использует собственно файл данных для этого. Очень странно на самом деле, что до этого дошли только через 20-30 лет, и тем не менее — полностью согласен. Не только проще — а надежнее (предсказуемее) — взять нормальную СУБД, если не стоит цели написать свою. Это не та задача которую можно поднять за год с приемлимым качеством.

И на правах токсичной фразы: 99% библиотек легко делаются за недельку с более чем приемлимым качеством, и в длинной перспективе — имеют дикий выигрыш. Главное только понимать, что того стоит, а что нет. Ну и в банальной прикладухе мои 99% они около 0%. Тем не менее, можно удивиться, тому, что какой-нибудь System.Text.Json не может десериализировать well-formed сообщение, просто потому что Стивен Тоуб считает всех за идиотов.
Re[6]: Транзакционная прокладка для файловой системы
От: VladD2 Российская Империя www.nemerle.org
Дата: 30.12.21 02:22
Оценка: 14 (1)
Здравствуйте, Mystic Artifact, Вы писали:

MA>Это не та задача которую можно поднять за год с приемлимым качеством.


На самом деле задача может быть не очень сложной, если решать ее не для общего случая, а для частного. Я как-то за пару дней написал БД для конкретного случая базы телефонных номеров спамеров. В ней, правда, транзакции были не нужны. БД формировалась при перегонке данных из кучи джейсонов, а читалась в ява-коде. Кличем был вырожденный случай Б-деревьев (нечто вроде кластерного индекса в Сиквеле). Работало это решение во много раз быстрее SQLite, так как было конкретным (использующим знание о хранимых данных).

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

А MSSQL штука дорогая и не всегда применимая. Я вот писал код для андроидного приложения. Какой там на фиг MSSQL? Вот SQLite там есть. Но откровенно говоря на андроидах он не блещет по скорости. Да и на ПК тоже.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: Транзакционная прокладка для файловой системы
От: vaa  
Дата: 30.12.21 06:35
Оценка: +1
Здравствуйте, VladD2, Вы писали:

VD>А MSSQL штука дорогая и не всегда применимая. Я вот писал код для андроидного приложения. Какой там на фиг MSSQL? Вот SQLite там есть. Но откровенно говоря на андроидах он не блещет по скорости. Да и на ПК тоже.

По деньгам? FILESTREAM не имеет ограничений на SQL EXPRESS к тому же ставится на линукс, а значит и на андроид можно теоретически, не интересовался. там правда обязательно должно быть более 4Гб ОЗУ.
SQLite не шустрый если часто сохранять, все стараются делать большую транзакцию и потом один раз фиксацию. Тогда скорость отличная.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.