Berkeley DB Reference Guide: Programmer Notes
Полезная информация

Berkeley DB Reference Guide: Programmer Notes

Error returns to applications

Except for the historic dbm, ndbm and hsearch interfaces, Berkeley DB does not use the global variable errno to return error values. The return values for all Berkeley DB functions can be grouped into three categories:

0
A return value of 0 indicates that the operation was successful.

> 0
A return value that is greater than 0 indicates that there was a system error. The errno value returned by the system is returned by the function, e.g., when a Berkeley DB function is unable to allocate memory, the return value from the function will be ENOMEM.

< 0
A return value that is less than 0 indicates a condition that was not a system failure, but was not an unqualified success, either. For example, a routine to retrieve a key/data pair from the database may return DB_NOTFOUND when the key/data pair does not appear in the database, as opposed to the value of 0, which would be returned if the key/data pair were found in the database. All such special values returned by Berkeley DB functions are less than 0 in order to avoid conflict with possible values of errno.

While possible error returns are specified by each individual function's manual page, there are a few error returns that deserve special mention:

EAGAIN

When multiple processes or threads of control are modifying the database, there is normally the potential for deadlock. In Berkeley DB, deadlock is signified by an error return from the Berkeley DB function of the errno value EAGAIN. Whenever a Berkeley DB function returns EAGAIN, the enclosing transaction should be aborted.

Any Berkeley DB function that attempts to acquire locks can potentially return EAGAIN. Practically speaking, the safest way to deal with applications that can deadlock is to handle a potential EAGAIN return from any Berkeley DB Access Method call.

DB_NOTFOUND and DB_KEYEMPTY

There are two special return values that are somewhat similar in meaning, are returned in similar situations, and therefore might be confused: DB_NOTFOUND and DB_KEYEMPTY.

The DB_NOTFOUND error return indicates that the requested key/data pair did not exist in the database or that start- or end-of-file has been reached.

The DB_KEYEMPTY error return indicates that the requested key/data pair logically exists but was never explicitly created by the application (the recno access method will automatically create key/data pairs under some circumstances, see db_open for more information), or that the requested key/data pair was deleted and is currently in a deleted state.

DB_RUNRECOVERY

There exists a class of errors that Berkeley DB considers fatal to an entire Berkeley DB environment. An example of this type of error is a log write failure due to the disk being out of free space. The only way to recover from these failures is for the application to exit, run recovery of the Berkeley DB environment, and re-enter Berkeley DB. (It is not strictly necessary that the application exit, although that is the only way to recover system resources, e.g., file descriptors and memory, currently allocated by Berkeley DB.)

When this type of error is encountered, the error value DB_RUNRECOVERY is returned. This error can be returned by any Berkeley DB interface. If a fatal error occurs, DB_RUNRECOVERY will be returned from all subsequent Berkeley DB calls made by any threads or processes participating in the environment.

Optionally, applications may also specify a fatal-error callback function by setting the db_paniccall field of the DB_ENV structure before initializing the environment with db_appinit. This callback function will be called with two arguments: a reference to the DB_ENV structure associated with the environment, and the errno value associated with the underlying error that caused the problem.

Applications can handle such fatal errors in one of two ways: by checking for DB_RUNRECOVERY as part of their normal Berkeley DB error return checking, similarly to EAGAIN or any other error, or, in applications that have no cleanup processing of their own, by simply exiting the application when the callback function is called.