Wietse Venema wrote:
Hallvard Breien Furuseth:
Wietse Venema writes:
(...) what happens when the two above activities happen in different processes? That is, process A (opens the database with MDB_NOLOCK. opens a cursor, and walks the database without making any changes to it), while process B opens the same database with MDB_NOLOCK and performs the delete transactions.
Will the process A cursor read transaction trigger an assertion due to the process B delete transactions? If not, why not?
Process A may see garbage data.
This is wrong. The fcntl locks will definitely prevent two processes from interfering with each other. The reason this bug occurs is because fcntl locks cannot prevent two transactions within a single process from stomping on each other.
This can result in an assert(), a
segfault or other misbehavior. Just like if you had process A == B. With MDB_NOLOCK, after a write transaction commits you need to end existing read-only transactions before starting a new writer. (Well, it's a bit looser than that, but that's a simple rule.)
Thanks for confirming my suspicion. I think that the correct option then is to use only short-lived cursor read transactions within fcntl()-protected blocks and to save/restore the previous cursor key where applicable.
Wietse