Fix: generous initial LMDB map size on environment open - #280
Conversation
|
@vtnerd could you please have a look |
|
Your attempted fix is to just make sure it never needs to resize, which isn't really a fix at all. Maybe a default of like 128 mib or so would be better, but 4 gib is just specific to your test case. The code is supposed to block all access once a thread enters the resize code. So the scan threads would actually halt while one of them updates the mapsize. Perhaps an actual gnu reader/writer lock would be better as it would sleep the threads, etc. instead of locking up the whole time slice The current code is very similar to what Monero daemon does, but Monero should have less concurrent accesses causing issues. |
|
Or perhaps the issue was the frequency at which the map needed resizing? That would lock things up for a while, even if the spin locks worked as intended. |
|
I tested it on regtest with 100 parallel scans, each with 10 subaddresses. The current version completely hangs and does not even return the status. This fix helped, but yes, we need to think about how to solve it in a better way. |
|
Do you have a 100-core CPU? Why so many workers? |
|
See if #281 fixes the issue you're having too. |
There were only 1500 regtest blocks, but the server completely froze. |
|
That wasn't my question - why so many worker threads? This definitely messes with the reader/writer spinlock as each thread is vying for a time slice on a limited number of compute cores. |
|
There was a misunderstanding. By 100 parallel scans, I meant 100 almost parallel sent The number of threads is the default one. |
Problem: the server would hang/livelock under concurrent scan load - CPU pegged, unresponsive even after a restart.
Root cause:
open_environment()never calledmdb_env_set_mapsize(), so LMDB opened at its own tiny built-in default (10 MiB) and had to grow via theMDB_MAP_RESIZED/MDB_MAP_FULLresize path almost immediately under any real write load. That resize path (resize()) busy-waits until there are zero active transactions - under concurrent scanning that condition can go unmet indefinitely, which is the livelock.Fix: call
mdb_env_set_mapsize(env, 4GB)right aftermdb_env_set_maxdbs, beforemdb_env_open- so the environment starts out generously sized and normal operation never needs to exercise that resize path in the first place.