Pregunta

Mi aplicación se bloquea al intentar abrir un almacén de datos concurrente (BDC) de base de datos para la lectura:

#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

Sospecho que el entorno de base de datos cree que otro proceso tiene la base de datos abierto para escritura. Esto no puede ser el caso, sin embargo, como todas las aplicaciones que acceden a la base de datos lo hacen a través de una biblioteca de interfaz escribí que registra una función de terminación a través de la atexit () de llamadas al sistema para asegurar que se dedique tanto a la DB y DB_ENV están correctamente cerrados - y todas las aplicaciones ejecutadas previamente terminado normalmente.

La biblioteca de interfaz se abre la base de datos de esta manera:

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 */

Este código encuentra ningún error.

La biblioteca de interfaz también registra el código siguiente a ser ejecutado cuando cualquier proceso que utiliza las salidas biblioteca de interfaz:

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 */
        }
    }
}

Como he indicado, todos los procesos ejecutados previamente que utilizan la biblioteca de interfaz terminados normalmente. Todos estos procesos son de un solo subproceso.

Estoy usando la versión 4.8.24.NC de Berkeley DB en la siguiente plataforma:

$ 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

¿Alguna idea?

scroll top