Exadra37
Mnesia with Memento lost all records for all tables
I have been developing an app in localhost, while keeping a staging version of the app running in another folder, with mix phx.server, that I use daily.
So, each time I shutdown or restart the laptop I don’t bother to manually stop it, but today I have stopped it accidentally with ctrl + c + c, and for my surprise when I started it again all my tables were empty
![]()
This was not the first time I have used ctrl + c + c to stop it, but never had this outcome.
I am using disc_copies tables, and I am not running in clustered mode.
application.ex:
def start(_type, _args) do
# Create the Schema
Memento.stop
Memento.Schema.create([node()])
Memento.start
# Create the DB with Disk Copies
# @TODO:
# Use Memento.Table.wait when it gets implemented
# @db.create!(disk: nodes)
# @db.wait(15000)
Memento.Table.create!(Users, disc_copies: nodes)
# omitted usual code
end
So what can I do to pinpoint the cause of this catastrophic lost?
Most Liked
keathley
Inspired by some of the discussions on this thread, I decided to play around with different failure modes with mnesia distribution: GitHub - keathley/breaking_mnesia · GitHub. I have a large test file that tries to explain my thought process. A cynical person could probably claim that these “failures” are either “working as intended” or “operator error”. My point wasn’t to try to say that mnesia is broken. My goal was to demonstrate the ways that Mnesia might be surprising if you’re expecting it to provide certain guarantees.
derek-zhou
You can make some simple API so you can access the app from the outside using curl or something simple. You need 2 API access:
- check data integrity, return ok or not
- do some random read write
Then you can make a shell script with an infinite loop:
- mix phy.server
- check integrity. If failed, stop right here
- random access
- kill -9
Then you can run it over night to see if you can trigger something.
vans163
The first thing that comes to mind is the node name changed, so the schema path changed. Like running
iex -S mix
then running
iex --sname test -S mix
The idea behind Mnesia is you MUST run it in at least 2 node configuration, as all writes go to both nodes, if 1 node has a power problem / CTRL+C+C, the other node will still receive the writes. (So 3 nodes total, your app + 2 noded mnesia). If you trip over the powercord to the rack hosting both nodes you are screwed and will lose (alot of) data.
Mnesia has no writeaheadlog like (all?) modern databases, it uses a log but its just an in-ram log that gets periodically flushed to disk. (This is why rocks_db backend for Mnesia is not a real solution to me, it doesnt add a WAL)
There was ways around it, you can set the logdumpthreshold to 1 millisecond, so mnesia will dump the log every 1ms. Or set it to 1 write (default is 1000 i think). But dumping this log is very cpu intensive and your tables will lock up as the dump is done, large tables will be rendered unwritable.
If you want to run Mnesia in a single local node configuration (just to store some persistent state for your app in a simple way), id run it with logdumpthreshold 1 write.








