Почему мое приложение одновременного хранилища данных Berkeley DB зависает?

StackOverflow https://stackoverflow.com/questions/2284688

Вопрос

Мое приложение зависает при попытке открыть базу данных одновременного хранилища данных (CDB) для чтения:

#0  0x0000003ad860b309 in pthread_cond_wait@@GLIBC_2.3.2 ()
   from /lib64/libpthread.so.0
#1  0x00007ffff7ce67de in __db_pthread_mutex_lock (env=0x610960, mutex=100)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../mutex/mut_pthread.c:318
#2  0x00007ffff7ce5ea5 in __db_tas_mutex_lock_int (env=0x610960, mutex=100, 
    nowait=0)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../mutex/mut_tas.c:218
#3  0x00007ffff7ce5c43 in __db_tas_mutex_lock (env=0x610960, mutex=100)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../mutex/mut_tas.c:248
#4  0x00007ffff7d3715b in __lock_id (env=0x610960, idp=0x0, lkp=0x610e88)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../lock/lock_id.c:68
#5  0x00007ffff7da1b4d in __fop_file_setup (dbp=0x610df0, ip=0x0, txn=0x0, 
    name=0x40b050 "registry.db", mode=0, flags=1024, retidp=0x7fffffffdd94)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../fileops/fop_util.c:243
#6  0x00007ffff7d70c8e in __db_open (dbp=0x610df0, ip=0x0, txn=0x0, 
    fname=0x40b050 "registry.db", dname=0x0, type=DB_BTREE, flags=1024, 
    mode=0, meta_pgno=0)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../db/db_open.c:176
#7  0x00007ffff7d673b2 in __db_open_pp (dbp=0x610df0, txn=0x0, 
    fname=0x40b050 "registry.db", dname=0x0, type=DB_BTREE, flags=1024, mode=0)
    at /home/steve/ldm/package/src/Berkeley-DB/dist/../db/db_iface.c:1146

Я подозреваю, что среда базы данных считает, что другой процесс открыл базу данных для записи.Однако это не может быть так, поскольку все приложения, обращающиеся к базе данных, делают это через написанную мной библиотеку интерфейса, которая регистрирует функцию завершения через системный вызов atexit(), чтобы гарантировать, что дескрипторы DB и DB_ENV правильно закрыты - и все ранее выполненные приложения завершились нормально.

Библиотека интерфейса открывает базу данных следующим образом:

int status;
Backend*    backend = (Backend*)malloc(sizeof(Backend));

if (NULL == backend) {
    ...
}
else {
    DB_ENV* env;

    if (status = db_env_create(&env, 0)) {
       ...
    }
    else {
        if (status = env->open(env, path,
                DB_CREATE | DB_INIT_CDB | DB_INIT_MPOOL, 0)) {
            ...
        }
        else {
            DB*     db;

            if (status = db_create(&db, env, 0)) {
            ...
            }
            else {
                if (status = db->open(db, NULL, DB_FILENAME, NULL,
                        DB_BTREE, forWriting ? DB_CREATE : DB_RDONLY, 0)) {
                    ...
                }
                else {
                    backend->db = db;
                }                   /* "db" opened */

                if (status)
                    db->close(db, 0);
           }                       /* "db" allocated */

           if (status) {
               env->close(env, 0);
               env = NULL;
           }
        }                       /* "env" opened */

        if (status && NULL != env)
            env->close(env, 0);
    }                               /* "env" allocated */

    if (status)
        free(backend);
}                                   /* "backend" allocated */

Этот код не обнаруживает ошибок.

Библиотека интерфейса также регистрирует следующий код, который будет выполняться при выходе любого процесса, использующего библиотеку интерфейса:

if (NULL != backend) {
    DB*         db = backend->db;
    DB_ENV*     env = db->get_env(db);

    if (db->close(db, 0)) {
        ...
    }
    else {
        if (env->close(env, 0)) {
            ...
        }
        else {
            /* database properly closed */
        }
    }
}

Как я указал, все ранее выполненные процессы, использующие библиотеку интерфейса, завершились нормально.Все такие процессы являются однопоточными.

Я использую версию 4.8.24.NC Berkeley DB на следующей платформе:

$ uname -a
Linux gilda.unidata.ucar.edu 2.6.27.41-170.2.117.fc10.x86_64 #1 SMP Thu Dec 10 10:36:29 EST 2009 x86_64 x86_64 x86_64 GNU/Linux

Есть идеи?

Это было полезно?

Решение

Приносим извинения, что этот вопрос так долго оставался без ответа.В будущем вы, возможно, захотите опубликовать свой вопрос на форуме Berkeley DB в сети Oracle Technology Network. здесь.Это очень активный форум, на котором напрямую взаимодействуют разработчики приложений, службы поддержки, инженеры и BDB.

Ваше описание проблемы подтверждает ваше предположение о том, что среда BDB может считать, что таблица уже открыта для записи.Вы можете использовать db_stat для просмотра статистики среды.Скорее всего, это проблема приложения, но один из инженеров BDB, вероятно, поможет вам локализовать проблему на форуме BDB, указанном выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top