私はかなり長い間SQLiteを使用しており、いくつかのロックの問題に対処する「幸運」がありました。SQLite がデフォルトで Unix ファイルシステムでバイト範囲ロックを使用していることは確かです。
より正確には、いくつかの代替ロック方法のコードが含まれています (例: dotlock スタイルflock()
のファイル全体ロックの使用)。オプションを指定してコンパイルすると、基礎となるファイルシステムの適切なロック方法を自動検出しようとします。SQLITE_ENABLE_LOCKING_STYLE
自動検出コードには、ハードコードされたケース (「ufs」、「nfs」、「smbfs」など) がいくつか含まれていますが、いずれも AFS ではありません。ハードコードされた大文字と小文字が一致しない場合、SQLite は を使用してファイルのバイト範囲ロックを取得しようとしますfcntl()
。fcntl()
次に、呼び出しが成功した場合、バイト範囲ロックが使用可能であると想定します。
ここで、OpenAFS の出番が興味深いものになります。どうやら ( [1]、[2]、[3] ) OpenAFS には、バイト範囲ロックについてユーザー空間アプリケーションに嘘をついた長い歴史があります。openafs-1.4.14
ソースコードから:
/* next line makes byte range locks always succeed,
* even when they should block */
if (af->l_whence != 0 || af->l_start != 0 || af->l_len != 0) {
DoLockWarning();
afs_PutFakeStat(&fakestate);
return 0;
}
一言で言えば:痛い!
これにより、バイト範囲ロックが何があっても成功します。Linux では、さらに悪いことが考えられます。カーネル インフラストラクチャを使用して、同じシステムのプロセス間でバイト範囲のロックを提供します。つまり、アプリケーションは単に新しいプロセスを fork してロック メカニズムをテストすることはできません。リモート プロセスからファイルを保護することは恐ろしく失敗していますが、バイト範囲のロックは正常に機能しているように見えます。
つまり、変更されていない SQLite を OpenAFS で確実に使用することはできません。他のほとんどのネットワーク ファイルシステムにも問題があるため、ネットワーク ファイルシステムを完全に回避することをお勧めします。
考えられるいくつかの回避策 (順不同):
PostgreSQLなどの適切な DBMS を使用します。これが可能であれば、長期的にはより良い状態になるでしょう。
本格的な DBMS が過剰な場合は、アプリケーション用に独自のサーバーを実装します。
flock()
OpenAFSでデフォルトになるように SQLite ソース コードを変更します。OpenAFS には、 plain-old でもロックの問題の長い歴史 ( [1]、[2] ) があるため、これが適切に機能するかどうかflock()
はわかりませんが、テストするまでわかりません。
カーネルを経由するのではなく、OpenAFS ユーザー空間を使用して、独自の OpenAFS VFS for SQLite を実装します。
別のネットワーク ファイルシステムで運試しをしてください。
何をするにしても、SQLite3 と共有データベース ファイルが何らかの形で関係する場合は、広範なテストを実行する必要があります。
編集:
コメンターは、ドットロック ファイル メカニズムの使用を提案しました。OpenAFS のソース コードについてはあまり掘り下げませんでしたが、一見するとopen(O_CREAT|O_EXCL)
、SQLite が使用する dotlock ファイルの作成方法をサポートしているように見えます。それが想定どおりに機能する場合、dotlock メソッドを使用するよう強制すれば、SQLite は実際に OpenAFS で使用できる可能性があります。
とは言うものの、ネットワーク ファイルシステムの複雑さをミックスに導入することなく、ドットロックは通常のローカル ファイルシステムでは十分な問題です。