|
|
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Есть файл 512MB, хочется атомарно дописать туда 128MB. Атомарно - значит что после Код: plaintext 1. во время которого упало питание, сдох процесс и т.п. я обнаруживаю файл в неком консистентном состоянии в том смысле, что отличаю внутри этого файла блоки с полезными данными от блоков с мусором. Дописать - не значит обязательно в конец и не значит, что одним последовательным куском. Можно заранее выделять в файле место и манипулировать страницами внутри. Как в любой файловой системе (fat32, ext3, ext4, другое) определить параметры атомарной записи? Вмысле, с какого смещения и сколько байт в файл записать, чтобы это гарантированно было атомарно? Например, предполагаю, что со смещений кратных 4096 писать размер блока 4096 - вполне атомарно для современных дисков с сектором 4096 байт, ибо файловая система кладёт файлы выравнивая их по секторам. Обсудите сабж. Предложите простейшую структуру данных в файле и алгоритм для обеспечения сего. P.S. Знаю про double buffering например, который вроде бы в InnoDB юзается: пишем последовательность страниц в этот буфер, делаем fsync(), потом поднявшись после падения достаём из этого буфера что там есть и распихиваем по месту назначения, делая fsync и очищая потом временный буфер. Но вопрос о размере атомарного блока остаётся. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 19:56 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
ReciprocatedЕсть файл 512MB, хочется атомарно дописать туда 128MB. Если так, то просто создай новый файл MyFile.tmp, запиши туда все с изменениями, затем переименуй старый в MyFile.bak, а этот на его место. Если писать в один и тот же файл, то предусмотри секцию где будут указаны места файла находящиеся в процессе записи, т.е. перед записью туда пишешь меняю там и там, в конце записи убирай, тогда при открытии файла, прочитав эту секцию, увидишь что было недописано. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 20:12 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Reciprocated, при данной постановке это невозможно. Ты просто можешь параллельно вести журнал атомарных операций. Например Код: plaintext 1. И при следующем ребуте детектировать факт потери 128 Mb. И предпринять какие-то действия по восстановлению. Пойти в веб или в БД и снова что-то выбрать или инициировать заново процесс калькуляций. Второй вариант. Если ты когда-либ работал с БД то там есть WAL (Write-Ahead-Log) или Redo-Log, и в нем будет вся история операций с начала консистентного старта системы. Но в случае с БД эти самые 128 Мб с неба не упали а были продуктом частичных более мелких транзакций и следовательно уже имеются в истории. И никуда они не потеряются. (По крайней мере dba в это верят). Но если ты счастливый обладатель дисковых хранилищ или каких-то хитрых псевдо-сетевых дисков то возможно шансы потерять инфу с С++ у тебя минимальны. Главное чтоб кусок в 128 Мб успешно улетел в сеть до отключения power. Но это уже не С++ а совершенно другие области знаний. И здесь я-бы послушал предложения специалистов в этой области. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 20:13 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
maytonНо это уже не С++ а совершенно другие области знаний. И здесь я-бы послушал предложения специалистов в этой области. ИМХУ если инфа важная, то УПС с обратной связью, который не даст неожиданно вырубится, а плавно выключит комп. Цена вопроса небольшая 3-5 т.р. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 20:21 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
если упало питание - это кранты. никакие программные примочки тебе не помогут. только если файл создать новый, потом перименовать. так поступают базы данных. сама файловая система после ткого збоя будет востанавливать данные. то есть ты не можешь такого гарантировать даже на нулевом кольце. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:01 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
ReciprocatedКак в любой файловой системе (fat32, ext3, ext4, другое) определить параметры атомарной записи? Никак, обломись. Для журналируемых систем есть соответствующие API, но для каждой - своё отдельное. Для остальных - просто обломись. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:15 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Reciprocatedво время которого упало питание, сдох процесс и т.п. я обнаруживаю файл в неком консистентном состоянии в том смысле, что отличаю внутри этого файла блоки с полезными данными от блоков с мусором.File Management Functions https://msdn.microsoft.com/en-US/library/windows/desktop/aa364232(v=vs.85).aspx См. все что связано с transacted operation. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:32 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovReciprocatedКак в любой файловой системе (fat32, ext3, ext4, другое) определить параметры атомарной записи? Никак, обломись. Для журналируемых систем есть соответствующие API, но для каждой - своё отдельное. Для остальных - просто обломись. Мне не нужны функции журналируемой ФС. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:45 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Alternatives to using Transactional NTFS https://msdn.microsoft.com/en-us/library/windows/desktop/hh802690(v=vs.85).aspx " It allows for Windows developers to have transactional atomicity for file operations in transactions with a single file, in transactions involving multiple files, ..." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:49 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
alexy_black если упало питание - это кранты. никакие программные примочки тебе не помогут. только если файл создать новый, потом перименовать. так поступают базы данных. сама файловая система после ткого збоя будет востанавливать данные. то есть ты не можешь такого гарантировать даже на нулевом кольце. Мужики-то не знали... особенно такие мужики: - которые сделали диски, дописывающие кеши после отрубания питалова - которые придумали WAL - которые придумали double buffering Как же тогда работают журналы в журналируемых ФС, сохраняя структуру этих ФС после всех отрубаний питалова. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:50 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Владимир2012Alternatives to using Transactional NTFS https://msdn.microsoft.com/en-us/library/windows/desktop/hh802690(v=vs.85).aspx " It allows for Windows developers to have transactional atomicity for file operations in transactions with a single file, in transactions involving multiple files, ..." Маркетинг буллшит. Не переходить же на другую ФС, если можно просто узнать размер блока и юзать fsync(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:54 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
ReciprocatedМне не нужны функции журналируемой ФС. Тогда не выпендривайся и используй атомарный rename. Или обломись. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:57 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Напоминаю задачу: нет задачи гарантированно записать данные. Есть задача оставить файл в консистентном состоянии, т.е. можно записать кусок кала, но при поднятии достать все старые данные и понять, что этот кусок является плохим. Текущее простое и сердитое решение, которое вроде бы это гарантирует. Кто считает, что не гарантирует - скажите конкретно где и почему. запись - хотим дописать 76 кб данных - добавляем в конец файла header постоянного размера, в который пишем hash данных + размер данных (76*1024) + hash самого header перед ним. - вызываем fsync() -- это как барьер памяти, не позволяющий переупорядочить операции записи перед ним и за ним - дописываем наши данные - вызываем fsync() чтение после сбоя 1. если header в неадеквате (файл кончился раньше размера header (он фиксир.), hash хидера не совпало) - считаем всё пространство файла далее пустым 2. если header вменяем, но в файле осталось меньше данных чем сказано в header или данных хватило, но их HASH не совпал с указанным в header - пункт (1) - считаем файл пустым, начиная с начала header ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:58 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovReciprocatedМне не нужны функции журналируемой ФС. Тогда не выпендривайся и используй атомарный rename. Или обломись. Чё-то ты не можешь отличить журнал ФС от журнала моего файла... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 21:58 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
ReciprocatedНе переходить же на другую ФС, если можно просто узнать размер блока и юзать fsync().Какую ОС и файловую систему используете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 22:06 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovReciprocatedМне не нужны функции журналируемой ФС. Тогда не выпендривайся и используй атомарный rename. Или обломись. +1 Тема не относится к С++ и к конструктивному обсуждению. Предлагаю автора с темой вернуть в ПТ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 22:10 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
SiemarglDimitry Sibiryakovпропущено... Тогда не выпендривайся и используй атомарный rename. Или обломись. +1 Тема не относится к С++ и к конструктивному обсуждению. Предлагаю автора с темой вернуть в ПТ. К С++ не относится, C++ тут как кейворд привлечения пытливых умов, ибо толпы тусующиеся вокруг других ключевых слов менее вероятно чё-нибудь дельное напишут. Модератор: Тема перенесена из форума "C++". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 22:14 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Нечестно обсуждать такую тему в С++. Пускай все участники сообщества тоже включаются. Перенес в Программинг ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 22:24 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Новая версия алгоритма. запись - пример: хотим добавить 76 кб данных - добавляем в конец файла header фиксированного размера, в который пишем hash данных + размер данных (76*1024). Можно записать hash этого header прямо перед ним самим - дописываем наши данные (76 kb payload) - вызываем fsync() - как барьер памяти. Порядок записи header1 и data1 неважен, лишь бы отделить эту пару от header2 и data2. чтение после сбоя 1. Открываем файл сначала и последовательно проверяем: если очередной header в неадеквате (файл кончился раньше размера header (он фиксир.), hash header-a не совпало) — считаем всё пространство файла начиная с header-а далее пустым. Потеряем только 1 запись, ведь в середине ничего не переписывали. 2. если header вменяем, но в файле осталось меньше данных чем сказано в header или данных хватило, но их hash не совпал с указанным в header - пункт (1) - считаем файл пустым, начиная с начала header ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 22:33 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
ReciprocatedНовая версия алгоритма. запись - пример: хотим добавить 76 кб данных - добавляем в конец файла header фиксированного размера, в который пишем hash данных + размер данных (76*1024). Можно записать hash этого header прямо перед ним самим - дописываем наши данные (76 kb payload) - вызываем fsync() - как барьер памяти. Порядок записи header1 и data1 неважен, лишь бы отделить эту пару от header2 и data2. чтение после сбоя 1. Открываем файл сначала и последовательно проверяем: если очередной header в неадеквате (файл кончился раньше размера header (он фиксир.), hash header-a не совпало) — считаем всё пространство файла начиная с header-а далее пустым. Потеряем только 1 запись, ведь в середине ничего не переписывали. 2. если header вменяем, но в файле осталось меньше данных чем сказано в header или данных хватило, но их hash не совпал с указанным в header - пункт (1) - считаем файл пустым, начиная с начала header 1. Должно работать. Если файл увеличен заранее - выделены кластеры и замаплены на сектора, то и ошибок файловой системы не должно быть. 2. Почему не std::fstream::flush ? 3. И что стало в условияем? "Дописать - не значит обязательно в конец и не значит, что одним последовательным куском." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 22:57 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Вася УткинReciprocatedНовая версия алгоритма. запись - пример: хотим добавить 76 кб данных - добавляем в конец файла header фиксированного размера, в который пишем hash данных + размер данных (76*1024). Можно записать hash этого header прямо перед ним самим - дописываем наши данные (76 kb payload) - вызываем fsync() - как барьер памяти. Порядок записи header1 и data1 неважен, лишь бы отделить эту пару от header2 и data2. чтение после сбоя 1. Открываем файл сначала и последовательно проверяем: если очередной header в неадеквате (файл кончился раньше размера header (он фиксир.), hash header-a не совпало) — считаем всё пространство файла начиная с header-а далее пустым. Потеряем только 1 запись, ведь в середине ничего не переписывали. 2. если header вменяем, но в файле осталось меньше данных чем сказано в header или данных хватило, но их hash не совпал с указанным в header - пункт (1) - считаем файл пустым, начиная с начала header 1. Должно работать. Если файл увеличен заранее - выделены кластеры и замаплены на сектора, то и ошибок файловой системы не должно быть. 2. Почему не std::fstream::flush ? 3. И что стало в условияем? "Дописать - не значит обязательно в конец и не значит, что одним последовательным куском." 1. Ok. Полезно выделить заранее кусман... 2. Не знал про такое, не важно как именно fsync() дёрнуть 3. Это не условие, а дозволение - оно есть по-прежнему. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 23:25 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
ReciprocatedВася Уткинпропущено... 1. Должно работать. Если файл увеличен заранее - выделены кластеры и замаплены на сектора, то и ошибок файловой системы не должно быть. 2. Почему не std::fstream::flush ? 3. И что стало в условияем? "Дописать - не значит обязательно в конец и не значит, что одним последовательным куском." 1. Ok. Полезно выделить заранее кусман... 2. Не знал про такое, не важно как именно fsync() дёрнуть 3. Это не условие, а дозволение - оно есть по-прежнему. 1. Ошибки ФС могут быть только при изменении размера файла, при условии, что сжатие в ФС отключено. 2. Возможно понадобятся оба: обязательно OS fsync() и возможно C++ flush() : http://stackoverflow.com/questions/2340610/difference-between-fflush-and-fsync/2340641#2340641 Например, так: http://stackoverflow.com/questions/676787/how-to-do-fsync-on-an-ofstream 3. А тут надо уточнить, "не значит обязательно в конец" - это значит перезаписывать середину, или сначала сдвигать все последующие блоки, а затем писать в свободную середину? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 23:52 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Reciprocated, 19649369 , 19649465 классная штука и должна работать, а на ntfs можно заюзать и файловые потоки. Только теперь нужно подумать как "атомарно" увеличить размер файла и как "атомарно" записать header. -- А может просто после каждой небольшой порции писать этот header(ECC,CRC). О, а диски у себя в патрохах так и делают! Так что rename.bak и/или write.log очень даже ФС независимо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.09.2016, 23:55 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Bred eFeMReciprocated, 19649369 , 19649465 классная штука и должна работать, а на ntfs можно заюзать и файловые потоки. Только теперь нужно подумать как "атомарно" увеличить размер файла и как "атомарно" записать header. -- А может просто после каждой небольшой порции писать этот header(ECC,CRC). О, а диски у себя в патрохах так и делают! Так что rename.bak и/или write.log очень даже ФС независимо. Атомарно размер файла увеличивать не надо. Атомарно записывать header не надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2016, 00:14 |
|
||
|
C++: атомарно записать в файл 128MB.
|
|||
|---|---|---|---|
|
#18+
Вася УткинReciprocatedпропущено... 1. Ok. Полезно выделить заранее кусман... 2. Не знал про такое, не важно как именно fsync() дёрнуть 3. Это не условие, а дозволение - оно есть по-прежнему. 1. Ошибки ФС могут быть только при изменении размера файла, при условии, что сжатие в ФС отключено. 2. Возможно понадобятся оба: обязательно OS fsync() и возможно C++ flush() : http://stackoverflow.com/questions/2340610/difference-between-fflush-and-fsync/2340641#2340641 Например, так: http://stackoverflow.com/questions/676787/how-to-do-fsync-on-an-ofstream 3. А тут надо уточнить, "не значит обязательно в конец" - это значит перезаписывать середину, или сначала сдвигать все последующие блоки, а затем писать в свободную середину? 1. Ок 2. Я не юзаю промежуточных буферов, сразу отправляю данные OS через ::write(), мне одного fsync() хватит 3. Не понял что вы хотите, если задача успешно вроде бы решена. Как хотите - можете поставить себе задачу придумать такую структуру данных и алгоритм, которые работают через запись в середину, тогда и разгребайте грабли сами и описывайте алгоритм. Решение с дописыванием в конец header + data решило задачу, я обошёлся без необходимости что-то ворочать в середине. Но если очень хочется - условия это не запрещают. Лишь бы новые данные каким-то образом консистентно добавились в хранилище без утечки "дисковой памяти" и с возможностью половинчатые записи потом увидеть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.09.2016, 00:19 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=39306927&tid=1340615]: |
0ms |
get settings: |
5ms |
get forum list: |
12ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
51ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 339ms |

| 0 / 0 |
