ページャーモジュール
SQLiteバージョン3以降のロックと同時アクセスは、ページャーモジュールによって処理されます。 このモジュールはACIDを担当します。 ページャーは、データベース、B-ツリー、インデックスなどのエンコードの詳細には関心がありません。その観点から、データベースは1から始まる同じサイズのブロック(ページ)に分割された単一のファイルです。ページャーはOSレイヤーを使用してオペレーティングシステムと通信しますインターフェース この投稿では、「スレッド」、「プロセス」、および「スレッド」は同等の概念です。
ロック
1つのプロセスの観点から見ると、データベースファイルは次の5つのロック状態のいずれかになります。
- ロック解除 -デフォルトの状態。 データベースのロックが解除され、どのストリームでもデータの読み取りと書き込みが可能になります。
- SHARED-データベースは読み取り可能ですが、書き込みはできません。
- 予約済み -プロセスはファイルへの書き込みを計画していますが、現在読み取り中です。 一度に1つのRESERVEDロックのみが可能です。 このモードとともに、 SHAREDロックを使用できます。
- PENDING-プロセスは、すべてのSHAREDロックの終了が記録を開始し、 排他モードに切り替わることを予期しています。
- EXCLUSIVE-プロセスはデータベースファイルに書き込みます。 これと並行して他のデータベースロックは許可されません。
以下は、データベースの整合性を保証するロールバックログを使用してデータを読み書きするアルゴリズムです。
データベースからデータを読み取るためのアルゴリズム
データベースから読み取るには、プロセスは次の手順を実行する必要があります。
- このアクションがSQLITE_BUSYによって返されない場合、データベースファイルを開き、 SHAREDロックを取得します。
- ベースにホットロールバックログがあるかどうかを確認します。 そうでない場合は、データベースからデータを読み取ることができます。 はいの場合、ステップ3。
- PENDINGを取得してから、 排他ロックを取得します。 ロックデータを取得する方法がない場合、別のプロセスがすでにロールバックしています。 この場合、すべてのロックを削除してSQLITE_BUSYを返します。
- ロールバックログとマスターログを読み取ります(複数のデータベースを接続すると、接続された各データベースのロールバックログに関するデータを保存する特別なファイル(マスタージャーナル)が作成されます)。
- ロールバック
- ロールバックログファイルを削除します(PRAGMAコマンドのjournal_modeオプションに応じて、さまざまな方法で削除が行われます)。
- 可能であれば、ログウィザードファイルを削除します。
- PENDINGロックとEXCLUSIVEロックを解除しますが、 SHAREDロックはそのままにしてデータベースを読み取ります。
データベースにデータを書き込むためのアルゴリズム
データベースにデータを書き込むには、プロセスは最初に次の手順を実行する必要があります。
- SHAREDロックを取得します(データベースからの読み取りアルゴリズム)。
- 予約済みロックを取得します。 これが不可能な場合は、 SQLITE_BUSYを返します。
- ロールバックログを作成します。 データベースのサイズとログウィザードの名前(存在する場合)は、ログのヘッダーに書き込まれます。
- データベース内のページに変更を加える前に、プロセスは最初にこのページをロールバックログに書き込みます。 変更されたページは主にRAMに書き込まれます。つまり、データベースファイルは変更されず、他のプロセスはデータベースからデータを読み取ることができます。 データの変更が終了してプロセスがCOMMITを生成している場合、またはメモリがいっぱいの場合は、手順5に進みます。
- すべてのロールバックログデータが実際にディスクに書き込まれたことを確認します。
- PENDINGを取得してから、 排他ロックを取得します。 ロックデータを取得できない場合は、データベースファイルが解放されるまで待つ必要があります。
- データベースファイル内のRAMからディスクにすべてのデータを書き込みます(書き込みの理由がRAMオーバーフローである場合は、手順4に戻ります)。
- ロールバックログファイルを削除します(PRAGMAコマンドのjournal_modeオプションに応じて、さまざまな方法で削除が行われます)。
- PENDINGおよびEXCLUSIVEロックを解放します。
アトミックコミットアルゴリズムについては、別の投稿で詳しく説明しています: habrahabr.ru/post/181584