私はずっと前からSQLiteを使用していましたが、いくつかのロック問題に対処する「幸運」がありました。私は、SQLiteがデフォルトでUnixファイルシステム上でバイトレンジロックを使用することはかなり確信しています。
より正確には、いくつかの代替のロック方法(たとえば、flock()
およびdotlock-style全体ファイルロックを使用)のコードが含まれています。 SQLITE_ENABLE_LOCKING_STYLE
optionでコンパイルすると、基礎となるファイルシステムの適切なロック方法を自動検出しようとします。
自動検出コードには、いくつかのハードコードされたケース(「ufs」、「nfs」、「smbfs」など)が含まれますが、いずれもAFSではありません。ハードコードされた大文字と小文字が一致しない場合、SQLiteはfcntl()
を使用してファイルのバイト範囲ロックを取得しようとします。次に、fcntl()
呼び出しが成功すると、バイト範囲のロックが使用可能であると仮定します。
OpenAFSがここに来て、物事を作るのには面白いです。です。明らかに([1],[2],)OpenAFSはlongのバイト範囲のロックに関するユーザー空間アプリケーションに嘘つきの履歴があります。 痛い:一言で
/* 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;
}
:openafs-1.4.14
ソースコードから!
これは、バイト範囲のロックが何であっても成功することを可能にします。 Linuxでは、カーネルインフラストラクチャを使用して、同じシステムのプロセスの中でバイト範囲のロックを提供することが考えられます。つまり、アプリケーションは新しいプロセスをフォークしてロック機構をテストすることはできません。バイト範囲のロックは正常に動作しているように見えますが、リモートプロセスからファイルを保護することは恐ろしくありません。
要するに、OpenAFSで修正されていないSQLiteを確実に使用することはできません。他のほとんどのネットワークファイルシステムにも問題があるため、ネットワークファイルシステムを完全に回避することを推奨します。順不同
いくつかの回避策:
はPostgreSQLとして、このように適切なDBMSを使用してください。これを行うことが可能ならば、長期的にはより良くなるでしょう。
本格的なDBMSが過度に使用されている場合は、アプリケーションに独自のサーバーを実装してください。
SQLiteソースコードをOpenAFSのデフォルトのflock()
に変更します。 OpenAFSは普通の古いflock()
でも長い問題([1]、[2])の問題をロックしているので、これが適切に動作するかどうかはわかりませんが、テストするまでわかりません。
OpenAFSユーザー空間を使用して、カーネルを経由するのではなく、独自のOpenAFS VFSを実装します。
別のネットワークファイルシステムであなたの運を試してください。
何をしても、SQLite3と共有データベースファイルが何らかの形で含まれている場合は、広範なテストを実行する必要があります。
EDIT:
コメンターはdotlockファイルのメカニズムを使用して提案しました。私はOpenAFSのソースコードを掘り下げていませんでしたが、一見すると、open(O_CREAT|O_EXCL)
SQLiteが使用するドットロックファイルを作成する方法をサポートしているようです。それが想定どおりに動作する場合、SQLiteは実際にOpenAFSで使用できるようになります。
しかし、dotlocksはネットワークファイルシステムの複雑さをミックスに導入することなく、通常のローカルファイルシステムには問題があります。それが私が最初に提案しなかった理由です。
+1確かに。しかし、AFSがアトミックなファイル作成を提供していると仮定すると、ドットロックは機能しませんか? – janneb
@janneb:OpenAFSソースw.r.tを確認しました。ドットロック。結果は勇気づけられました - またはドットロックを含む何かが可能であるように励ましてください。 – thkala