###

Berkeley DB Reference Guide:
  Debugging Applications

# Common errors

This page outlines some of the most common problems that people encounter and some suggested courses of action.

Symptom:
  Core dumps or garbage returns from random Berkeley DB operations.

Possible Cause:
  Failure to zero out DBT structure before issuing request.

Fix:
  Before using a DBT, you must initialize all its elements to 0 and then set the ones you are using explicitly.

Symptom:
  Random crashes and/or database corruption.

Possible Cause:
  Running multiple threads, but did not specify DB_THREAD to DB->open or DB_ENV->open.

Fix:
  Any time you are sharing a handle across multiple threads, you must specify DB_THREAD when you open that handle.

Symptom:
  DB_ENV->open returns EINVAL.

Possible Cause:
  The environment home directory is a remote mounted filesystem.

Fix:
  Use a locally mounted filesystem instead.

Symptom:
  DB->get calls are returning EINVAL.

Possible Cause:
  The application is running with threads, but did not specify the DB_DBT_MALLOC, DB_DBT_REALLOC or DB_DBT_USERMEM flags in the DBT structures used in the call.

Fix:
  When running with threaded handles (that is, specifying DB_THREAD to DB_ENV->open or DB->open), you must specify one of those flags for all DBT structures in which Berkeley DB is returning data.

Symptom:
  Running multiple threads or processes, and the database appears to be getting corrupted.

Possible Cause:
  Locking is not enabled.

Fix:
  Make sure that you are acquiring locks in your access methods. You must specify DB_INIT_LOCK to your DB_ENV->open call and then pass that environment to DB->open.

Symptom:
  Locks are accumulating, or threads and/or processes are deadlocking, even though there is no concurrent access to the database.

Possible Cause:
  Failure to close a cursor.

Fix:
  Cursors retain locks between calls. Everywhere the application uses a cursor, the cursor should be explicitly closed as soon as possible after it is used.

Symptom:
  The system locks up.

Possible Cause:
  Application not checking for DB_LOCK_DEADLOCK.

Fix:
  Unless you are using the Concurrent Data Store product, whenever you have multiple threads and/or processes and at least one of them is writing, you have the potential for deadlock. As a result, you must test for the DB_LOCK_DEADLOCK return on every Berkeley DB call. In general, updates should take place in a transaction, or you might leave the database in an inconsistent state. Reads may take place outside the context of a transaction under common conditions.

  Whenever you get a DB_LOCK_DEADLOCK return, you should do the following:

  1. If you are running in a transaction, abort the transaction after first closing any cursors opened in the transaction.

  2. If you are not running in a transaction, simply close the cursor that got the DB_LOCK_DEADLOCK (if it was a cursor operation), and retry.

  See Recoverability and deadlock avoidance for further information.

Symptom:
  An inordinately high number of deadlocks.

Possible Cause:
  Read-Modify-Write pattern without using the RMW flag.

Fix:
  If you frequently read a piece of data, modify it and then write it, you may be inadvertently causing a large number of deadlocks. Try specifying the DB_RMW flag on your get calls.

  Or, if the application is doing a large number of updates in a small database, turning off Btree splits may help (see DB_REVSPLITOFF for more information.)

Symptom:
  I run recovery and it exits cleanly, but my database changes are missing.

Possible Cause:
  Failure to enable logging and transactions in the database environment; failure to specify DB_ENV handle when creating DB handle; transaction handle not passed to Berkeley DB interface; failure to commit the transaction.

Fix:
  Make sure that the environment and database handles are properly created, that the application passes the transaction handle returned by DB_ENV->txn_begin to the appropriate Berkeley DB interfaces, and that each transaction is eventually committed.

Symptom:
  Recovery fails.

Possible Cause:
  A database was updated in a transactional environment, both with and without transactional handles.

Fix:
  If any database write operation is done using a transaction handle, every write operation must be done in the context of a transaction.

Symptom:
  A database environment locks up, sometimes gradually.

Possible Cause:
  A thread of control exited unexpectedly, holding Berkeley DB resources.

Fix:
  Whenever a thread of control exits holding Berkeley DB resources, all threads of control must exit the database environment, and recovery must be run.

Symptom:
  A database environment locks up, sometimes gradually.

Possible Cause:
  Cursors are not being closed before transaction abort.

Fix:
  Before an application aborts a transaction, any cursors opened within the context of that transaction must be closed.

Symptom:
  Transaction abort or recovery fail, or database corruption occurs.

Possible Cause:
  Log files were removed before it was safe.

Fix:
  Do not remove any log files from a database environment until Berkeley DB declares it safe.

Copyright Sleepycat Software