Berkeley DB 同時データ ストア アプリケーションがハングするのはなぜですか?
-
21-09-2019 - |
質問
読み取りのために同時データ ストア (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
データベース環境では、別のプロセスがデータベースを書き込み用に開いていると認識しているのではないかと思います。ただし、データベースにアクセスするすべてのアプリケーションは、DB ハンドルと DB_ENV ハンドルの両方が適切に閉じられるようにするために、atexit() システムコールを介して終了関数を登録する、私が作成したインターフェイス ライブラリを介してアクセスするため、これは当てはまりません。そして、以前に実行されたすべてのアプリケーションは正常に終了しました。
インターフェイス ライブラリは次のようにデータベースを開きます。
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 */
}
}
}
先ほど示したように、インターフェイス ライブラリを使用する以前に実行されたプロセスはすべて正常に終了しました。このようなプロセスはすべてシングルスレッドです。
次のプラットフォームで Berkeley DB のバージョン 4.8.24.NC を使用しています。
$ 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
何か案は?
解決
この質問はあまりにも長い間未解決の行ったことの謝罪。将来的には、あなたはrel="nofollow">ここのOracle Technology Networkの
問題のご説明はBDB環境はテーブルが既に書き込みアクセスのために開いていることを考えることが、あなたの仮定を検証します。あなたは、環境の統計を見てdb_statを使用することができます。これはおそらく、アプリケーションの問題ですが、BDBのエンジニアの一つは、おそらくあなたは上記のBDBフォーラムに問題を特定に役立つ可能性があります。