Products
Berkeley DB
最終更新日:2007年7月26日
標準
・
Oracle Berkeley DBデータベースは、SQL"表"と同じものですか。
・
個別の監視プロセスを使用せずに、マルチプロセスのOracle Berkeley DBアプリケーションを設計する方法を教えてください。
・
アプリケーション情報をデータベースまたはデータベース環境ハンドルと関連づける方法を教えてください。
・
Oracle Berkeley DBのExport Control Classification Number(ECCN)は何番ですか。
インストールと構築
・
MFCまたはoledb.hを含むものを使用してプロジェクトを作成するときに、Windowsでコンパイル・エラーが発生するのはなぜですか。
・
Visual C++バージョン6を使用したWindows Releaseの構築が失敗するのはなぜですか。
トラブルシューティング
・
lockers、locks、lockオブジェクトを使い果たした場合はどうすればよいですか。
・
Oracle Berkeley DBからエラー番号12または22が返されました。これはどういう意味ですか。
・
ディスク領域を使い果たすとデータベースが破損してしまいます。
・
1つの物理ファイルに複数のデータベースを作成すると、データベースが破損してしまいます。
・
アプリケーションの終了に時間がかかり、ディスクの回転音が聞こえます。
・
"unable to initialize mutex: Function not implemented"エラーが表示されるのはなぜですか。
・
Windowsのコールバックにメモリを割り当てたあとで、メモリ障害が発生するのはなぜですか。
・
ソフトウェア分析ツール(Rational Software Corp.のPurifyツールなど)を実行中に、初期化されていないメモリの読取りおよび書込みのレポートが表示されるのはなぜですか。
データベースとアクセス方式
・
Oracle Berkeley DBの操作をおこなうと、EINVALのようなエラーが返されます。APIは正しく使用しています。
・
Oracle Berkeley DBデータベースは、整数サイズやバイト・オーダーが異なるアーキテクチャ間で移植可能ですか。
・
物理データベース・ファイルのサイズを調べる方法を教えてください。
・
カーソルを繰り返し動かすことなく、データベース内のキーを数える方法はありますか。
・
キーとデータのペアの存在をもっとも素早く確認する方法は何ですか。
・
データベースを圧縮して、未使用のデータベース・ページをファイル・システムに戻す方法はありますか。
・
DB_FREE_SPACEフラグを使用しているときに、空のページを解放して、ファイル・システムに戻すためにコンパクト・メソッドを使用できないのはなぜですか。
・
セカンダリ重複のカスタム・ソートを実行する方法を教えてください。
データベース環境
・
データベース環境のチェックポイント機能により、データベースへのアクセスがブロックされることがありますか。
・
トランザクション・データベース環境が停止し、操作が進行している制御スレッドがありません。
・
データベースに対する同時アクセスが存在しないにもかかわらず、トランザクション環境でロックが累積している、またはスレッドとプロセス、あるいはそのいずれかがデッドロックになっています。
・
トランザクション・データベース環境をリカバリできない、または通常のデータベース操作が、"LSN" values are past the end of the logのメッセージを表示して失敗します。
・
トランザクション・アプリケーションで、異常に多い数のデッドロックが発生します。
トランザクション
・
Oracle Berkeley DBから次のエラーが表示されることがあります。 "Unable to allocate memory for transaction detail" これはどういう意味ですか。
・
DB_AUTO_COMMITフラグをデータベース・カーソルとともに使用する方法を教えてください。
ファイル・システム
・
Oracle Berkeley DBでは、NFS、SAN、またはそのほかのリモート・ファイル・システム、共有ファイル・システム、ネットワーク・ファイル・システムをデータベースおよびデータベース環境に使用できますか。
・
Oracle Berkeley DBでは、データをRAWディスクのパーティションに格納できますか。
・
Oracle Berkeley DBのデータベース・ストレージに最適なLinuxファイル・システムは何ですか。
パフォーマンス
・
Btreeデータベースのキーとして整数を使用しています。キーとデータのペアはソート順に入力しているにもかかわらず、page-fillファクタが低くなってしまいます。
・
Oracle Berkeley DBシステムのダブル・バッファリングを回避する方法はありますか。
Oracle Berkeley DBデータベースは、SQL"表"と同じものですか。
はい。"表"はデータベース、"行"はキーとデータのペア、"列"はアプリケーション・カプセル化フィールドとなります。 アプリケーションは、特定のフィールド、またはデータ値内の"列"にアクセスするための独自の方式を提供する必要があります。
個別の監視プロセスを使用せずに、マルチプロセスのBerkeley DBアプリケーションを設計する方法を教えてください。
詳しくは、『Berkeley DB Reference Guide』の"Handling failure in Transactional Data Store applications"の項および"Architecting Transactional Data Store applications"の項を参照してください。
アプリケーション情報をデータベースまたはデータベース環境ハンドルと関連づける方法を教えてください。
C APIでは、各DBハンドルおよびDB_ENVハンドルに、アプリケーション固有の情報を参照するために使用される"app_private"フィールドが含まれています。 詳しくは、db_createおよびdb_env_createのドキュメントを参照してください。
C++ APIまたはJava APIで、アプリケーション固有のデータとハンドルを関連づけるもっとも簡単な方法は、DbハンドルおよびDbEnvハンドルをサブクラスにする方法です。たとえば、MyDbを取得するためにDbをサブクラス化します。 タイプMyDbのオブジェクトでは、引き続きOracle Berkeley DB APIメソッドを使用可能なので、任意の追加データまたはメソッドをMyDbクラスに追加できます。 Db引数またはDbEnv引数をとる"コールバック"API(たとえば、Db.set_bt_compareメソッド)を使用する場合、それらは常に、ユーザーが作成するDbオブジェクトまたはDbEnvオブジェクトとともにコールされます。 そのため、常にMyDbオブジェクトを使用する場合は、最初の引数をコールバック関数に渡し、MyDb(C++では、(MyDb*)にキャストできます。 これで、自分のデータ・メンバーまたはメソッドにアクセスできます。
Oracle Berkeley DBのExport Control Classification Number(ECCN)は何番ですか。
オープン・ソース製品であるOracle Berkeley DBは、標準の輸出規制の対象にはなりません。 ただし、Oracle Berkeley DBにはオプションで、強力な暗号のサポートが含まれることがあります。暗号化ソフトウェアの輸出入および使用、または暗号化ソフトウェアの技術詳細を伝達することさえ、世界の一部地域では違法となります。 暗号法を含んでいるOracle Berkeley DBのリリースを自国に輸入する、または何らかの方法でそのソース・コードを再配布する場合は、適用される輸出入法規および使用に関する法律に細心の注意を払うことを強く推奨します。 そのような懸念がある場合は、強力な暗号のサポートが含まれていないOracle Berkeley DBのバージョンを使用することを推奨します。
MFCまたはoledb.hを含むものを使用してプロジェクトを作成するときに、Windowsでコンパイル・エラーが発生するのはなぜですか。
Oracle Berkeley DBのヘッダー・ファイル
db.hおよびMicrosoftのヘッダー・ファイル
oledb.hは、いずれも記号
DBTYPEを定義します。 いずれかのヘッダー・ファイルでこの記号の使用方法を変更すると、既存のコードが壊れます。
この問題に対する最初のもっとも簡単な解決策は、ソース・コードを整理して、これら2つのヘッダー・ファイルのうち1つだけがソース内で必要となるようにすることです。 つまり、Oracle Berkeley DBの使用とMicrosoftのOLE DBライブラリの使用を切り離して、コード内で混合しないようにします。
それから、
db.hまたは
oledb.hの一方を選択し、1つのソース・ファイル内で混合しないようにします。
一方だけ選択することができず、両方のヘッダーを混合する必要がある場合は、以下のように
#include行の1つをラップします。
ソース・コードで
oledb.hが含まれている行を検索します。 これは自動生成された
stdafx.hインクルード・ファイル内にある場合があります。 そのヘッダー・ファイルが本当に必要かどうかを判断します。 必要な場合は、次のinclude行を
#include <oledb.h>
以下のように変更します。
/* Work around DBTYPE name conflict with Berkeley DB */
#define DBTYPE MS_DBTYPE
#include <oledb.h>
#undef DBTYPE
次に、MicrosoftのDBTYPEを使用する必要がある場合は、MS_DBTYPEとして参照します。
また、Cアプリケーションの場合は、
db.hのinclude行を同様の方法でラップできます。
このテクニックを使用して、
db_cxx.hをラップすることはできません。 Oracle Berkeley DBに対してC++インタフェースを使用している場合は、
oledb.hと
db_cxx.hの混合を避けるか、上述のように
oledb.hのinclude行をラップする必要があります。
Visual C++バージョン6を使用したWin32 Releaseの構築が失敗するのはなぜですか。
Oracle Berkeley DB 4.3.29に含まれているVisual C++プロジェクト・ファイルには、Visual C++バージョン6で使用した場合のバグが含まれています。現象は、リンク時に以下のエラーが生成されるというものです。
Linking... Creating library Release/libdb43.lib and object Release/libdb43.exp mut_win32.obj : error LNK2001: unresolved external symbol __imp__SetSecurityDescriptorDacl@16 mut_win32.obj : error LNK2001: unresolved external symbol __imp__InitializeSecurityDescriptor@8 Release/libdb43.dll : fatal error LNK1120: 2 unresolved externals Error executing link.exe.
このリリースでは、リンク時にadvapi32.libという追加ライブラリが必要になります。 このライブラリはプロジェクト・ファイルに含まれていますが、Visual C++バージョン6では認識されません(バージョン7.0以降ではこの問題は発生しません)。
解決策は、以下の手順に従い、db_dllターゲットのビルドにこのライブラリを手動で追加することです。
lockers、locks、lockオブジェクトを使い果たした場合はどうすればよいですか。
Oracle Berkeley DB環境では、一定数のlockers、locks、およびlockオブジェクトに対するメモリが保持されます。そのため、これらのリソースを使い果たしてしまう可能性は常にあります。
割り当てられるlockリソースの最大数は、データベース環境の作成時に設定されます。そのため、この最大数を変更するには、lockers、locks、またはlockオブジェクトの数を増やして、環境を再作成する必要があります。
詳しくは、『Berkeley DB Reference Guide』の"Configuring locking: sizing the system"の項を参照してください。
Oracle Berkeley DBからエラー番号12または22が返されました。これはどういう意味ですか。
アプリケーションのOracle Berkeley DB APIをコールする方法が間違っているか、不十分なリソースでデータベース環境を構成しています。
Oracle Berkeley DBライブラリは、一般的な目的のエラーを返す、または抽象的な例外をスローする場合は常に詳細なエラー・メッセージを出力します。 Oracle Berkeley DBへのアプリケーション・コールが失敗する理由がわからない場合、最初の手順は常に、詳細なエラー・メッセージを確認することです。メッセージを読めばほとんどの場合、問題が明らかになります。
詳しくは、『Berkeley DB Reference Guide』の"Run-time error information"項を参照してください。
Oracle Berkeley DBでは、エラー・ネームスペースがどのように分割されるのかを理解しておくのも役立ちます。 歴史のあるdbm、ndbm、およびhsearchインタフェースを除き、Oracle Berkeley DBではエラーの値を返すためにグローバル変数のerrnoは使用しません。 Oracle Berkeley DBのすべての関数の戻り値は、以下の3つのカテゴリに分類されます。
戻り値0は、操作が正常終了したことを示します。
0より大きい戻り値は、システム・エラーが発生したことを示します。 システムから戻されるerrno値は、関数から戻される値です。たとえば、Oracle Berkeley DBの関数がメモリを割り当てられない場合、その関数からの戻り値は
ENOMEMとなります。0未満の戻り値は、システム障害は発生していないが、無条件の正常終了でもない状態を示します。 たとえば、データベースからキーとデータのペアを取得するルーチンは、データベースに該当するキーとデータのペアがない場合、
DB_NOTFOUNDを返します。データベースにキーとデータのペアが存在する場合は、0が返されます。
Oracle Berkeley DBの関数から戻される値はすべて、errnoで想定される値と競合するのを避けるために0未満になっています。 具体的には、Oracle Berkeley DBでは、可能なエラーの値として、-30,800から-30,999が予約されています。 アプリケーションの関数をOracle Berkeley DBの関数からコールできる、ごく一部のOracle Berkeley DBインタフェースでは、障害時にアプリケーション固有の戻り値が返されます。 そのような障害の戻り値は、Oracle Berkeley DBインタフェースを最初にコールした関数に返されます。 エラーの原因が不明確になるのを避けるためには、Oracle Berkeley DBのエラー・ネームスペースから離れたエラーの値を使用する必要があります。
また、Oracle Berkeley DBがdb_strerror関数から返すエラー番号に関連づけられているメッセージ文字列はいつでも取得できます。 db_strerror関数は、ANSI C X3.159-1989 (ANSI C) strerror(3)関数のスーパーセットです。 エラー番号が0以上の場合は、システム関数strerror(3)から戻される文字列が返されます。 エラー番号が0未満の場合は、対応するOracle Berkeley DBのライブラリ・エラーに適したエラー文字列が返されます。
ディスク領域を使い果たすとデータベースが破損してしまいます。
Oracle Berkeley DBは、out-of-disk-spaceエラーが発生しても稼動し続けることができますが、トランザクションはアプリケーションで保護する必要があります。 トランザクションでの更新操作が組み込まれていないアプリケーションは、out-of-disk-spaceエラーからリカバリできません。その結果、ディスク領域を使い果たすとデータベースが破損する場合があります。
1つの物理ファイルに複数のデータベースを作成すると、データベースが破損してしまいます。
この問題は通常、データベース・ハンドルが基礎となるデータベース環境を共有していないために起こります。 詳しくは、『Berkeley DB Reference Guide』の"Opening multiple databases in a single file"の項を参照してください。
アプリケーションの終了に時間がかかり、ディスクの回転音が聞こえます。
Oracle Berkeley DBアプリケーションがデータバース・ハンドルを破棄するためにデータベース・ハンドルのクローズ・メソッドをコールする場合、キャッシュ内のダーティ・ページがバッキング・データベース・ファイルにデフォルトで書き込まれます。 この動作を変更するには、DB_NOSYNCフラグをDb.closeに指定します(Java APIを使用している場合は、noSyncフラグをDatabase.closeメソッドに指定します)。 このフラグを設定することで、ハンドルのクローズ・メソッドはキャッシュ内のダーティ・ページを無視します。
多くのアプリケーションでは、データベース・ハンドルのクローズ・メソッドがコールされたときに、キャッシュのダーティ・ページをフラッシュする必要はありません。 永続性のためにトランザクションまたはレプリケーションを使用するアプリケーションでは、トランザクションのメカニズムによりデータの損失は発生しないので、ダーティ・ページをフラッシュする必要はありません。 また、データベース環境が削除されそうにならない限り、キャッシュからダーティ・ページをフラッシュする必要はありません。 プロセスは、キャッシュに保持されているダーティ・ページをフラッシュすることなく、データベース環境に加わり、離れることができます。データベース環境が再びアクセスされることがない場合のみ、ダーティ・ページをバッキング・ファイルにフラッシュする必要があります。
"unable to initialize mutex: Function not implemented"エラーが表示されるのはなぜですか。
Oracle Berkeley DBアプリケーションでこのエラーが発生するもっとも一般的な理由は、システムがOracle Berkeley DBによって構成された基礎となるミューテックスをコールし、それがシステムで使用できないため、ENOSYSを返すということです(これは、"Function not implemented"メッセージと関連づけられているシステム・エラーです)。
一般的にこのエラーは、Oracle Berkeley DBライブラリ・ビルドがPOSIXミューテックスを使用するように構成されており、POSIXミューテックスがこのシステムで使用できない場合、またはライブラリがPOSIXミューテックスを使用可能な別のシステムで構成されたあとで、POSIXミューテックスを使用できないシステムに物理的に移動された場合に発生します。
このエラーは、Linuxシステムで発生することがあります。これは、一部のLinuxシステムでは、POSIXミューテックスのサポートがCライブラリ構成にあり、オペレーティング・システムにはないため、または、システムにあるPOSIXミューテックスのサポートがイントラプロセス・ミューテックスのためだけのものであり、インタープロセス・ミューテックスのものではないためです。
このエラーを回避するには、Oracle Berkeley DBが使用するミューテックス実装を、 --with-mutex=MUTEX構成フラグとともに明示的に指定します。
--with-mutex=MUTEX
To force Berkeley DB to use a specific mutex implementation,
configure with --with-mutex=MUTEX, where MUTEX is the mutex
implementation you want. For example,
--with-mutex=x86/gcc-assembly will configure Berkeley DB to use
the x86 GNU gcc compiler based test-and-set assembly mutexes.
This is rarely necessary and should be done only when the
default configuration selects the wrong mutex implementation. A
list of available mutex implementations can be found in the
distribution file dist/aclocal/mutex.ac
Windowsのコールバックにメモリを割り当てたあとで、メモリ障害が発生するのはなぜですか。
Windowsの場合、各コンポーネントで使用されるビルド・フラグによっては、アプリケーションが複数のバージョンの標準割当てルーチン(malloc、realloc、およびfree)を使用する場合があります。 また、割当てがおこなわれるコード内の場所によっては、複数のヒープからメモリが割り当てられることがあります。
そのため、アプリケーションがmallocバージョンの割当てルーチンで一部のメモリを割り当てたあとで、Oracle Berkeley DBがfreeバージョンの 割当てルーチンを使用してそのメモリにアクセスを試みるとメモリ障害が発生する場合があります。
解決策は、DB_ENV->set_allocメソッドを使用してから、DB_ENV->openをコールすることです。 Cの場合:
dbenv->set_alloc(dbenv, malloc, realloc, free);
C++の場合:
dbenv->set_alloc(::malloc, ::realloc, ::free);
ソフトウェア分析ツール(Rational Software Corp.のPurifyツールなど)を実行中に、 初期化されていないメモリの読取りおよび書込みのレポートが表示されるのはなぜですか。
パフォーマンス上の理由から、Oracle Berkeley DBでは、データベース・ページの未使用部分の書込み、または未使用の構造フィールドの埋込みはおこないません。 ソフトウェア分析ツールの実行中にこれらのエラーが発生しないようにするには、Oracle Berkeley DBを--enable-umrw構成オプションで構成してから構築します。
Oracle Berkeley DBの操作をおこなうと、EINVALのようなエラーが返されます。APIは正しく使用しています。
アプリケーションが、Oracle Berkeley DBをコールする前にDBTオブジェクトの消去に失敗しています。 DBTを使用する前に、DBTのすべての要素を0に初期化してから、使用する要素を明示的に設定する必要があります。
この現象が生じる別の理由に、アプリケーションが、DB_THREADフラグをDB->openメソッドまたはDB_ENV->openメソッドに指定せずに、フリー・スレッド方式でm4_dbハンドルを使用している場合があります。 複数のスレッド間でハンドルを共有する場合は常に、そのハンドルをオープンするときにDB_THREADを指定する必要があります。
この現象が生じるもう1つの理由としては、アプリケーションがロックを取得せずにデータベースに同時にアクセスしている場合が考えられます。 Oracle Berkeley Database Data Store製品にはロック機能はありません。そのため、アプリケーションが独自にデータベースへのアクセスをシリアライズして、破損を回避する必要があります。 Oracle Berkeley Database Concurrent Data Store製品およびOracle Berkeley Database Transactional Data Store製品にはデータベースのロック機能がありますが、ロック機能はユーザーが構成する必要があります。
Oracle Berkeley DBデータベースは、 整数サイズやバイト・オーダーが異なるアーキテクチャ間で移植可能ですか。
はい。 具体的には、32ビット・マシンと64ビット・マシン間、およびリトルエンディアン・マシンとビッグエンディアン・マシン間でデータベースを移動できます。 詳しくは、『Berkeley DB Reference Guide』の"Selecting a byte order"の項を参照してください。
物理データベース・ファイルのサイズを調べる方法を教えてください。
この情報は、DB->statメソッドで得られます。
カーソルを繰り返すことなく、データベース内のキーの数を数える方法はありますか。
DB->statメソッドを使用して、キーとデータ項目の数を取得できます。詳しくは、メソッドのドキュメントを参照してください。
キーとデータのペアの存在をもっとも素早く確認する方法は何ですか。
DB->existsメソッドを使用する方法です。
データベースを圧縮して、未使用のデータベース・ページをファイル・システムに戻す方法はありますか。
Oracle Berkeley DBのすべてのアクセス・メソッドでは、空になったデータベース・ページはほかで使用できるようになります。つまり、未使用のページが存在する限り、基礎となるファイル・システムから新しいページが割り当てられることはありません。 また、Btreeデータベースは実行時に圧縮でき、DB->compactメソッドをコールすることで、ファイル・システムにページを返すことができます。 さらに、Queueアクセス・メソッドのエクステント・ファイルは、空になると削除され、それらのページは基礎となるファイル・システムに返されます。
DB_FREE_SPACEフラグを使用しているときに、空のページを解放して、ファイル・システムに戻すためにコンパクト・メソッドを使用できないのはなぜですか。
揮発性データベースでコンパクト・メソッドを利用する予定の場合、データベースはその独自のファイルに常駐させることを推奨します。 単一のファイルにデータベースx、y、zがあり、データベースxを圧縮して、空になったページをファイル・システムに解放する場合、データベースy、zによって、それらのページのファイル・システムへの解放が妨げられる可能性があります。 DB_FREE_SPACEフラグを設定してコンパクト・メソッドを実行する場合、空のページは空きページ・リストに入りますが、ファイル・システムには解放されません。 ファイルからスペースを解放するには、ファイルの最後に空きページが存在する必要があります。また、ほかのデータベース(y、z)にはそれらのページが含まれていることがあり、とくに、それらのデータベースのメタデータ・ページは絶対に解放できません。
セカンダリ重複のカスタム・ソートを実行する方法を教えてください。
ソート済みの重複が構成されたセカンダリ・データベースが存在する場合は、プライマリ・レコードのほかのフィールドを基準にして重複をソートできます。 たとえば、セカンダリ・キーがF1で、重複の順序付けに使用する別のフィールドF2がプライマリ・レコードにある場合、 F2で順序付けされた重複で、F1をセカンダリ・キーとして使用できます。
Oracle Berkeley DBでは、セカンダリ・データベースのための"データ"が主キーです。 セカンダリ・キーで重複が認められている場合、重複比較関数では、それらの主キーの値が比較されます。 したがって、プライマリ・レコードは比較関数では使用できないため、重複比較関数はF2でソートするためには使用できません。
Oracle Berkeley DBのキーおよび重複比較関数の目的は、単純なバイト単位の比較以外の方法で値のソートを可能にすることにあります。 一般的に、キーまたは重複エントリに存在しないレコード・データを使用するキーまたは重複を順序付けするための方法を提供するためのものではありません。 比較関数は非常に頻繁にコールされる(Btree操作が実行されるときは常にコールされます)ので、迅速に比較できることが重要になります。
F2でソートをおこなう方法には、次の2つの方法があります。
オプション#1には、F2で自動的にソートがおこなわれる利点があります。 ただし、F1キー単独でDatabase.joinメソッドを使用した結合をおこなうことはできません。 F1+F2値で結合をおこなうことはできますが、これはあまり有用ではありません。
多くの場合は、セカンダリ・キーが結合に使用されます。 そのため、F1で結合をおこなう必要がないとわかっている場合を除き、オプション#2を推奨します。
トレードオフは以下のとおりです。
データベース環境のチェックポイント機能により、データベースへのアクセスがブロックされることがありますか。
チェックポイントによって、Oracle Berkeley DBデータベース環境へのアクセスがブロックされることはありません。制御スレッドは、チェックポイント中もデータベースの読取りおよび書込みを継続できます。 ただし、チェックポイントによって大量のI/Oが発生する可能性がある場合、ほかの制御スレッドの操作が遅くなり、アクセスがブロックされているように感じることがあります。
DB_ENV->memp_trickleメソッドを使用して、チェックポイントで実行する必要があるI/Oを分散できます。ENV->memp_trickleメソッドにより、指定した割合のページがキャッシュ内にクリーンな状態で保持されます。 また、DB_ENV->memp_set_max_writeメソッドを使用して、DBライブラリによってスケジュールされる順次書込み操作の数を制限することもできます。 DB_ENV->memp_set_max_writeメソッドは、データベース・キャッシュをフラッシュするすべてのメソッド(チェックポイントやDB->syncなどのほかのメソッド)に作用します。
トランザクション・データベース環境が停止し、操作が進行している制御スレッドがありません。
この障害のもっとも一般的な原因は、Berkeley DBミューテックス、または読取り/書込みの論理データベース・ロックを保持している間に、制御スレッドが突然終了するというものです。 制御スレッドがデータ構造ミューテックスを保持したまま終了すると、ほかの制御スレッドは瞬時にロックされ、ミューテックスのあとでキューに入れられます。 制御スレッドが論理データベース・ロックを保持したまま終了すると、ほかの制御スレッドは、長期間ロックされることがあります。これは、ロックを使用できない特定のページの取得を試みるまでブロックされないためです。 デッドロックのデバッグについて詳しくは、『Berkeley DB Reference Guide』の"Deadlock debugging"の項を参照してください。
制御スレッドがミューテックスまたは論理ロックを保持しているm4_dbを終了する場合は常に、障害を解決する必要があります。 詳しくは、『Berkeley DB Reference Guide』の"Handling failure in Transactional Data Store applications"の項を参照してください。
さらに、Oracle Berkeley DB APIはリエントラントではないので、通常、シグナル・ハンドラでOracle Berkeley DBメソッドをコールするのは安全ではありません。 詳しくは、『Berkeley DB Reference Guide』の"Signal handling"の項を参照してください。
データベースに対する同時アクセスが存在しないにもかかわらず、トランザクション環境でロックが累積しているか、スレッドおよびプロセス、あるいはそのいずれかがデッドロックになっています。
アプリケーションが、カーソルを閉じられない可能性があります。 カーソルにはコール間のロックが保持されます。 アプリケーションは、カーソルを使用するすべての場所で、使用したあとできるだけ早くカーソルを明示的に閉じる必要があります。
この現象が起きる別の理由としては、アプリケーションがDB_LOCK_DEADLOCKエラー(C++ APIまたはJava APIでは、DbDeadlockException例外)をチェックしていないことがあります。 Oracle Berkeley Database Concurrent Data Store製品を使用している場合を除き、複数のスレッドまたはプロセス、あるいはその両方がデータベースに同時にアクセスしており、少なくとも1つがデータベースに書込みをおこなっている場合は常にデッドロックが発生する可能性があります。
デッドロックが発生する場合は、アプリケーションでデッドロック障害をテストし、エンクロージング・トランザクションを中断する必要があります。中断しないと、ロックはそのまま残ります。 詳しくは、『Berkeley DB Reference Guide』の"Recoverability and deadlock handling"の項を参照してください。
トランザクション・データベース環境をリカバリできません。または通常のデータベース操作が、"LSN"値がログの終端を超過しているというメッセージを表示して失敗します。
アプリケーションが、データベースのログ順序番号(LSN)をリセットせずに、アプリケーションのログ・ファイルをすべて削除している可能性があります。 ログ・ファイルは、db_archiveユーティリティまたはDB_ENV->log_archiveメソッドで明示的に許可されている場合を除き、絶対に削除しないでください。 それらのインタフェースで、 すべての既存ログ・ファイルの削除が許可されることはありません。
この現象が生じる別の理由としては、アプリケーションがあるトランザクション環境でデータベース・ファイルを作成したあとで、そのファイルを別のトランザクション環境に移動している場合があります。 バルク・データベース・ロードをおこなう場合などに、データベースを非トランザクション環境で作成したあとで、トランザクション環境に移動することは可能ですが、一度トランザクション環境で使用されたデータベースは、まずデータベースのログ順序番号をリセットしてからでないと、別の環境に移動できません。 詳しくは、DB_ENV->lsn_resetメソッドのドキュメントを参照してください。
トランザクション・アプリケーションで、異常に多い数のデッドロックが発生します。
アプリケーションが一貫性のない順番でデータベース・オブジェクトを取得している可能性があります。制御スレッドが常に同じ順番でオブジェクトを取得するようにすると、デッドロックの頻度が減少します。
データを読み取り、変更してから書き込む操作を頻繁におこなっている場合、無意識のうちに大量のデッドロックを引き起こしていることになります。 getコールにはDB_RMWフラグを指定するようにしてください。
さらに、分離レベルを削減することで、アプリケーションが遭遇するデッドロックの数を大幅に減らせます。 詳しくは、『Berkeley DB Reference Guide』の"Isolation"の項および"Degrees of isolation" の項を参照してください。
Oracle Berkeley DBから次のエラーが表示されることがあります。 "Unable to allocate memory for transaction detail" これはどういう意味ですか。
このエラーは、Oracle Berkeley DB用に構成されたアクティブなトランザクションの最大数に達したという意味です。 より多くのアクティブなトランザクションをサポートするようにOracle Berkeley DB環境を構成する必要があります。 データベース環境でトランザクションに使用可能なすべてのメモリが使用中の場合、トランザクションを実行するためのコールは、いくつかのアクティブなトランザクションが完了しない間は失敗します。 デフォルトでは、データベース環境は最低20のアクティブなトランザクションをサポートするように構成されます。
詳しくは、『Berkeley DB Reference Guide』の"Configuring transactions"の項を参照してください。
DB_AUTO_COMMITフラグをデータベース・カーソルとともに使用する方法を教えてください。
DB_AUTO_COMMITフラグは、カーソルには適用されません。 カーソル操作用のトランザクションが必要な場合は、明示的なトランザクションを作成して使用する必要があります。
Oracle Berkeley DBでは、NFS、 SAN、またはそのほかのリモート・ファイル・システム、共有ファイル・システム、ネットワーク・ファイル・システムをデータベースおよびデータベース環境に使用できますか。
これは難しい質問です。 答えは、想像されるほど明白なものではありません。
Oracle Berkeley DBは、SAN(およびそのほかの既知のファイル・システム・タイプ)とともに十分に機能しますが、複数のマシンから任意のファイル・システムにアクセスを試みる場合、そのファイル・システムを共有のリモート・ファイル・システムとして扱っていることになり、Oracle Berkeley DBで問題が生じる原因となります。 詳しくは、『Berkeley DB Reference Guide』の"Remote filesystems"の項を参照してください。
共有ファイル・システム、リモート・ファイル・システム、ミューテックス、およびキャッシュの一貫性に関しては次の2つの問題があります。
たとえば、マシンAがリモート・ファイル・システムのデータベース環境をオープンし、マシンBも同様にオープンしたあと、マシンAがそのリモート・ファイル・システムにバックアップされているミューテックスを取得した場合、そのミューテックスはマシンBを正しくシリアライズできません。これは、両方のマシンが1つのデータ構造を同時に変更している可能性があり、その結果、想像できるあらゆる悪い現象がデータベースに起こりうるということです。
たとえば、マシンAがデータベースのページ5を読み取り(ページ5はページ6を参照)、マシンBがデータベースのページ6に書き込んでから、マシンAがデータベースのページ6を読み取る場合、マシンAには一貫性のないページ5と6が存在することになります。この結果、正しくないまたは一貫性のないデータがアプリケーションに戻され、さらにはコア・ダンプに出力されることになります。
このシナリオでは、コア・ダンプおよび一貫性のないデータはリーダーにのみ限定して出力されるため、アプリケーションのなかにはそれを受け入れるものもあります。
もちろん、Oracle Berkeley DB以外のデータベースへのアクセスをシリアライズすることは可能ですが、システム全体のパフォーマンスに大幅な影響を与えることになります。
そのため、Oracle Berkeley DBは、ネットワーク・ファイル・システムまたはSANのいずれかで使用可能な共有ディスク上のデータベース環境に対する複数システムの同時アクセスを完全にサポートするようには設計されていません。
Oracle Berkeley DBでは、データをRAWディスクのパーティションに格納できますか。
Oracle Berkeley DBは、RAWディスクのパーティションを使用するようには設計されていません。理由は以下のとおりです。
1つ目は、RAWディスクのパーティションを使用するには、専用のアーカイブ、チューニング、およびそのほかのデータベース管理ツールが必要になる点です。これは、物理データベースやほかのファイルにアクセスするためのツールは簡単に作成できないためです。 Oracle Berkeley DBの設計では、データベース管理に既存のツールを使用することは許可されています(たとえば、ホット・バックアップのための、POSIX cp、tar、またはpaxユーティリティの使用)。その結果、ローカル環境への緊密な統合を実現しています。 これは、Oracle Berkeley DBのライセンスをおこなっているサード・パーティのソフトウェア・ベンダーにとっても利点となります。ベンダーは、非標準のアーカイブ・プロシージャまたはツールが必要となることや、同様のものを作成して顧客に提供することを望まないからです。 別の理由は、RAWパーティションを拡張するのは困難または不可能であるため、データベースのインストール・サイズを変更するのが非常に難しくなる点です。 Oracle Berkeley DBと同様に、ファイル・システムを使用する場合、別のパーティションまたはディスクをマウントするだけで済みます。 (Oracle Berkeley DBデータベースのアプリケーションは、多くのデータベース製品とは異なり、使用可能なディスク領域がない場合でも稼動し続けることができます。これは、ほかのアプリケーションがディスク領域からBerkeley DBアプリケーションを実行できるため、ディスク領域不足に対する回復力をBerkeley DBに備える必要があったためです)。
2つ目は、RAWパーティションはあまりパフォーマンスの向上に貢献していないという点です。少なくとも現代的なオペレーティング・システムにおいてはあまり影響がありません。 事前書込みロギング・データベース・システムにおけるトランザクションのパフォーマンスは、通常、ログ・ファイルの書込みによって制限されます。ログ・ファイルは順番に書き込まれ、ファイルを順番に書き込むことで、ファイル・システムのオーバーヘッドが最小限に抑えられます。 操作の待機時間の観点から、Oracle Berkeley DBは、キャッシュで読込みまたは書込みができない場合のみファイル・システムにアクセスします。 確かに、ワーキング・セットが使用可能なキャッシュに収まらないデータセットも存在しますが、多くはありません。 つまり、Oracle Berkeley DBをRAWパーティションに移植しても、ワーキング・セットがキャッシュに収まっているアプリケーションのパフォーマンスは向上しません。 システムに100GBのキャッシュを設置すれば、かなり大きなワーキング・セットを処理できます。
3つ目は、RAWパーティションの"ファイル"に名前をつける、ファイルにブロックを割り当てる、ファイルを拡張するなどをおこなうには大量の追加コードが必要になる点です。 ファイル・システムに非常によく似たレイヤーを作成する必要があり、Oracle Berkeley DBのフットプリントを大幅に増やすことになります。また、コードは継続的な移植やパフォーマンスのチューニングを必要とします。 Oracle Berkeley DB が独自のファイル・システムに実装されている場合、新しいドライバの追加、ディスク・パフォーマンスの最適化作業に時間をかける必要があり、それらは、当社が専門とする分野ではなく、付加価値を提供できる分野でもありません。 既存のアーキテクチャの場合、顧客はOracle Berkeley DBを新しいハードウェアで稼動させられるかどうかを心配する必要はありません。稼動するとわかっているのです。 さらに、Oracle Berkeley DBは、基礎となるファイル・システムをチューニングする、または新しいファイル・システムを新しい種類のディスク(たとえば、ソリッドステート・ディスク、NVRAMディスク、または新しいRAIDデバイス)に対して展開する場合に、自動的によりよいパフォーマンスを実現します。
いくつか理由を述べましたが、RAWパーティションへの移植に対する強力な1つの反対理由は、ダブル・バッファリング(Berkeley DBデータベース・ページのコピーが、Berkeley DBキャッシュとオペレーティング・システムのバッファ・キャッシュの両方に保持されている状態)を回避することにあります。 現代のオペレーティング・システムでは、Berkeley DBキャッシュと直接コピーを出し入れするようにI/Oを構成できるため、OSバッファ・キャッシュとダブル・バッファリングを回避できます。
RAWパーティションにデータベースを作成するには、Oracle Berkeley DBに大幅に変更を加える必要はありません。 基礎となるopen、read、write、およびlseekインタフェースのコールをRAWパーティションで機能するように置き換えるだけです。 ただし、Oracle Berkeley DBがその環境で完全に機能するようにするには、データベース環境の一般的な管理機能が現状どおりスムーズに機能するようにするための多くの作業が必要になります。 なお、サード・パーティの研究者たちが、Oracle Berkeley DBでこの実験をおこなっています。 彼らの研究内容はいかなる種類のものであれ入手できませんが、プルーフ・ポイントとしての役目を果たしています。
Oracle Berkeley DBのデータベース・ストレージに最適なLinuxファイル・システムは何ですか。
TPアプリケーションに対してもっとも優れたパフォーマンスをもつLinuxファイル・システムはext2だと考えています。しかし、ext2にはorderedデータ・モードがないため、使用するとデータが破損する可能性があります。 この理由から、当社ではext3の使用を推奨しています。パフォーマンスもよく、orderedデータ・モードもサポートされています。 XFSのパフォーマンスを測定した情報はありませんが、フィールドにおける障害は確認しています(XFSには、ファイルを繰り返し拡張するアプリケーションにおける問題があります。ファイルを繰り返し拡張することは、Oracle Berkeley DBデータベースでの一般的な使用パターンです)。
Btreeデータベースのキーとして整数を使用しています。キーとデータのペアはソート順に入力しているにもかかわらず、page-fillファクタが低くなってしまいます。
これは通常、x86などのリトルエンディアン・アーキテクチャで整数キーを使用しているために生じます。 Oracle Berkeley DBではバイト文字列としてキーがソートされるため、リトルエンディアン整数は、バイト文字列として表示する場合、うまくソートされません。 たとえば、数値254から257を例にすると、リトルエンディアン・システムでのバイト・パターンは次のようになります。
254 fe 0 0 0
255 ff 0 0 0
256 0 1 0 0
257 1 1 0 0
これらを文字列として扱う場合、次のようにうまくソートされません。
256
257
254
255
ビッグエンディアン・システムでは、それぞれのバイト・パターンは次のようになります。
254 0 0 0 fe
255 0 0 0 ff
256 0 0 1 1
257 0 0 1 1
そのため、これらを文字列として扱う場合は、うまくソートされます。 これは、ビッグエンディアン・システムのキーとして確実に増加する整数を使用する場合、Oracle Berkeley DBはうまく動作し、コンパクト・ツリーを取得できますが、リトルエンディアン・システムのOracle Berkeley DBでは生成されるコンパクト・ツリーは少なくなります。 この問題を回避するには、キーをフラット・テキスト表現またはビッグエンディアン表現に変換するか、 DB->set_bt_compareメソッドを使用して、独自のBtree比較関数を提供します。
Oracle Berkeley DBシステムのダブル・バッファリングを回避する方法はありますか。
ダブル・バッファリングを完全に回避することはできませんが、この問題に対応するためにできることはいくつかあります。
1つ目として、Oracle Berkeley DBのキャッシュ・サイズは明示的に設定できます。 ダブル・バッファリングは、Oracle Berkeley DBのキャッシュに追加のスペースを割り当てて、予想外に高い負荷やサイズの大きい表に対応するのではなく、通常の条件で十分に機能するようにキャッシュのサイズを設定し、異常な条件での対応はファイル・バッファ・キャッシュに任せることを示唆しています。 これは、明らかにトレードオフです。Oracle Berkeley DBは異常な条件下では通常どおりのパフォーマンスを発揮しません。
2つ目として、使用している基礎となるオペレーティング・システムによっては、ファイル・バッファ・キャッシュ用の物理メモリの量を変更できます。 システム・スーパーユーザーとして実行することで、一部のUNIXまたはUNIXに似たオペレーティング・システムでの動作に違いがでます。
3つ目として、Oracle Berkeley DB環境領域のサイズを変更することで、オペレーティング・システムでバッファ・キャッシュが使用可能なスペースの量を変更できます。また、多くの場合、オペレーティング・システムが使用可能なメモリをどのように分割するのかを厳密に検討すると役立ちます。 さらに、Oracle Berkeley DBのデータベース環境領域をファイル・システムのバックアップ・メモリからシステム・メモリ(またはヒープ・メモリ)に移動することで、多くの場合、とくに、統一されたバッファ・キャッシュのないシステムやVMシステムのファイル・バッファ・キャッシュに対して追加のシステム・メモリを使用できるようになります。
最後に、バッファリングをオフにできるオペレーティング・システムの場合は、DB_DIRECT_DBフラグとDB_DIRECT_LOGフラグを指定して、オフにするようにします。