Skip to content

Fix: generous initial LMDB map size on environment open - #280

Open
mahnunchik wants to merge 1 commit into
vtnerd:masterfrom
mahnunchik:mapsize
Open

Fix: generous initial LMDB map size on environment open#280
mahnunchik wants to merge 1 commit into
vtnerd:masterfrom
mahnunchik:mapsize

Conversation

@mahnunchik

Copy link
Copy Markdown
Contributor

Problem: the server would hang/livelock under concurrent scan load - CPU pegged, unresponsive even after a restart.

Root cause: open_environment() never called mdb_env_set_mapsize(), so LMDB opened at its own tiny built-in default (10 MiB) and had to grow via the MDB_MAP_RESIZED/MDB_MAP_FULL resize 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 after mdb_env_set_maxdbs, before mdb_env_open - so the environment starts out generously sized and normal operation never needs to exercise that resize path in the first place.

@mahnunchik

Copy link
Copy Markdown
Contributor Author

@vtnerd could you please have a look

@vtnerd

vtnerd commented Jul 27, 2026

Copy link
Copy Markdown
Owner

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.

@vtnerd

vtnerd commented Jul 27, 2026

Copy link
Copy Markdown
Owner

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.

@mahnunchik

Copy link
Copy Markdown
Contributor Author

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.

@vtnerd

vtnerd commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Do you have a 100-core CPU? Why so many workers?

@vtnerd

vtnerd commented Jul 30, 2026

Copy link
Copy Markdown
Owner

See if #281 fixes the issue you're having too.

@mahnunchik

Copy link
Copy Markdown
Contributor Author

Do you have a 100-core CPU? Why so many workers?

There were only 1500 regtest blocks, but the server completely froze.

@vtnerd

vtnerd commented Jul 31, 2026

Copy link
Copy Markdown
Owner

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.

@mahnunchik

Copy link
Copy Markdown
Contributor Author

There was a misunderstanding. By 100 parallel scans, I meant 100 almost parallel sent import_wallet_request requests.

The number of threads is the default one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants