multiple writer processes with Berkeley DB

Recently I was evaluating Berkeley DB usability when multiple unrelated processes try to write to the same database. My early attempts to create a small working example code failed badly and I was unsure whether the multiple writer approach is something that isn’t supposed to work at all or if there was a bug in the DB or in my exploration code. Issue resolved now.

My code opens an environment and a database pair ten times in a loop, writing hundred records for each iteration. Running the example ten times in a row results in the expected 10000 records. However, running the example ten times in parallel causes all kinds of problems from error messages “DB_PAGE_NOTFOUND”, “Requested page not found”, “fatal region error detected” etc. to lost data and segmentation faults. Same issue on FreeBSD/x86, FreeBSD/amd64, RHEL4/ix86 and Solaris9/SPARC64. Environment and DB were placed on local filesystem.

The code is pretty much verbatim taken from the reference manual with hints from the FAQ
How can I architect a multi-process Berkeley DB application …?

Berkeley DB version used db-4.5.20.2-20070507.src.rpm from spec

Berkeley DB stress test batch and probe

I was asking this in the Oracle Technology Network Discussion Forum.

Finally I found out the correct usage. DB_INIT_MPOOL and DB_INIT_LOCK were required. Also important is the need to pass dbenv to db_create().

All fixed, see patch

Only one minor issue remains. The creation of the database does not work as I expected it when attempted by parallel running processes. If I try, like the original test.sh did, then some processes fail with “File exists” error. My assumption is that early processes recognize the DB is missing and needs creation. The fastest process wins the race, works as designed. The immediate followers fail, which is behavior I did not expect. The very slow processes find the DB and do not attempt to create it, also works as designed. My current workaround is to do first time database access, which includes DB_CREATE, by a single process only.

Leave a Reply