MMKV icon indicating copy to clipboard operation
MMKV copied to clipboard

Func 'doFullWriteBack' in place update mmap file, will corrupt file when func is not finished but process exit.

Open CodeLife2012 opened this issue 3 years ago • 13 comments

  memmoveDictionary
----
  vec.reserve(dic.size());
   or (auto &itr : dic) {
        vec.push_back(&itr.second);
  }

Dict is written back follow the vec order. When crashed in the middle, recoverd key value pairs in the file are not follow the order user set it, may contain some old value and some new value, but lost the others.

So unfinished write back may put the key value pairs in a crazy state silently.

CodeLife2012 avatar Aug 01 '21 13:08 CodeLife2012

I test the code, aborted the process when doFullWriteBack is running. Func checkDataValid report check crc failed, then the file is cleared.

CodeLife2012 avatar Aug 01 '21 17:08 CodeLife2012

I don't quite understand your English. You might consider using an online-translater or just use your native language.

lingol avatar Aug 02 '21 02:08 lingol

At my best guess, you were complaining about MMKV lost data if the App crash/exit while MMKV is doing a full writeback? That's an acceptable failure. But what's your suggestion?

lingol avatar Aug 02 '21 02:08 lingol

@lingol You should use a new file instead of updating the mmap file directly, clear the mmap file only when keys are actually saved to the new file.

CodeLife2012 avatar Aug 02 '21 02:08 CodeLife2012

And if the App crash while replacing the mmap file with the newly created file, what then?

lingol avatar Aug 02 '21 02:08 lingol

@lingol Should delete old file first, then rename new file.

CodeLife2012 avatar Aug 02 '21 02:08 CodeLife2012

Corrupting the file sounds like a red flag. Writing to a tmp file and renames it is a better solution, this also enable us to "rollback" should the write failed.

LightYearsBehind avatar Aug 02 '21 02:08 LightYearsBehind

But you cannot guarantee an atomic delete & rename operation, yes? Losing data is still possible. And we are back to square one.

lingol avatar Aug 02 '21 02:08 lingol

How about keeping 2 files and versions it, so we don't delete any file in this case. What's left is to decide which version to use then.

LightYearsBehind avatar Aug 02 '21 03:08 LightYearsBehind

@lingol If old file exist, recover from the old file. If crashed before rename but after delete, use the new file.

CodeLife2012 avatar Aug 02 '21 03:08 CodeLife2012

That whole switching file logic is way too expensive for a full writeback, which happens all the time, and finishes quite quickly if it's only a memory operation. Given the pros and cons of each solution, I'm not sold to go for the switching file solution.

lingol avatar Aug 02 '21 03:08 lingol

Func doFullWriteBack will call sync(MMKV_SYNC) to sync the m_file and m_metaFile.

CodeLife2012 avatar Aug 02 '21 04:08 CodeLife2012

it may sound a bit expensive writing the full file for each single write of an entry. for sure it will remove a class of problems related of the to corruption of a file during writing, but the cost seems quite high.

what about having this option per file? I can still see cases where data integrity is more important than performance (I'm having in mind cases where you have only a small set of key-values and a full rewrite cost is bearable) and you can leave the decision to the developer

carlonzo avatar Apr 26 '22 08:04 carlonzo