Problems with secondary indices 4.4.20 - 04-25-2006 , 04:26 PM
I'm currently experiencing two problems related to secondary indices.
I'm using a transactional environment and accessing from separate
1. When I update the primary record by replacing the record, I get an
additional entry in the secondary. It's configured for DUPSORT, but the
result is an unsorted secondary index
2. More importantly, if I try to access the data from the secondary
using c_pget, and from the other process try to update with a put, both
operations lock. Lock timeouts don't seem to resolve the situation.
Obviously, this is bad.
Re: Problems with secondary indices 4.4.20 - 04-25-2006 , 06:38 PM
When you say you get and additional entry in the secondary, do you mean
that there are two secondary entries for a single primary record? If
so, that's obviously bad. If that is the case, can you send a test
case to support (AT) sleepycat (DOT) com?
With regards to locking, it certainly is possible for deadlocks to
occur when accessing secondaries: do you have deadlock detection
enabled (either with DB_ENV->set_lk_detect or by running a deadlock
Re: Problems with secondary indices 4.4.20 - 04-26-2006 , 09:56 AM
For case 1:
Yes. I'll submit a report, but here's what seems to be happening:
1. Insert primary record, secondary record produced.
2. Update primary record using c_put( ....., DB_CURRENT). New secondary
For case 2:
I didn't have the set_lk_detect active before. It now recovers from the
deadlock, but I still don't understand how it occurs. Why does c_pget
require a write lock on the primary? And if it needs it, why doesn't it
try to lock the primary first?
Re: Problems with secondary indices 4.4.20 - 04-26-2006 , 08:08 PM
Do you have any custom comparison callbacks on the secondary? (Either
DB->set_bt_compare or DB->set_dup_compare). Invalid comparison
functions could lead to the kind of behavior you're describing.
As far as locking is concerned, the c_pget call doesn't require write
locks, but the read locks it takes will block with the write locks
acquired by the c_put. There is no way to lock the primary first when
you start with a secondary key -- DB doesn't know what page in the
primary to lock.
In fact, the c_put code attempts to lock the secondary first, but when
updating an existing primary record, we need to know what is being
overwritten in order to remove the old secondary entries, which means
that the primary has to be locked before the secondary.
Re: Problems with secondary indices 4.4.20 - 04-27-2006 , 02:31 PM
OK, I'm kind of confused by this. If we can't read from the secondaries
without causing deadlocks, doesn't that make secondaries useful only
for read-only databases?
Isn't there any way to read a secondary while allowing the primary to
write without causing deadlocks? While I could certainly rework the
code to handle timeouts, that would have an unacceptable impact on my
application. Not only will the timeouts be a significant delay, but it
will make the application response time overly dependant on lock
contention. At this point my only alternative seems to be implementing
my own secondary indexes independantly of that provided by BDB.