SQLite、複数クライアントからの同時書き込みを可能にする「BEGIN CONCURRENT」文を実装へ

今回は「SQLite、複数クライアントからの同時書き込みを可能にする「BEGIN CONCURRENT」文を実装へ」についてご紹介します。

関連ワード (実装、慎重、操作等) についても参考にしながら、ぜひ本記事について議論していってくださいね。

本記事は、Publickey様で掲載されている内容を参考にしておりますので、より詳しく内容を知りたい方は、ページ下の元記事リンクより参照ください。


SQLiteの開発チームは、複数クライアントからの同時書き込みを可能にするBEGIN CONCURRENT文を実装していることを明らかにしました。

これまでSQLiteでは書き込みの同時実行はできず、つねに1つのクライアントだけが書き込み可能でした。

fig

同時書き込み処理は、データベースのジャーナルモードが「wal」(Write-Ahead-log)もしくはwalを改良した「wal2」で、BEGIN CONCURRENT文を実行した場合に可能となります。

どのように同時書き込み処理が行われるのかについては、上記のWebページの説明を引用しましょう。

ロックが延期されることで同時書き込みが可能に

まず、書き込み時のロックがCOMMITまで延期されることで同時書き込みが実現されると説明されています。

When a write-transaction is opened with “BEGIN CONCURRENT”, actually locking the database is deferred until a COMMIT is executed. This means that any number of transactions started with BEGIN CONCURRENT may proceed concurrently. The system uses optimistic page-level-locking to prevent conflicting concurrent transactions from being committed.

BEGIN CONCURRENTによって書き込みトランザクションが開始されると、COMMITが実行されるまでデータベースのロックは延期されます。これによりBEGIN CONCURRENTで開始されたトランザクションは複数同時に実行できるようになります。
システムは楽観的ページレベルロッキングにより競合している同時トランザクションがコミットされるのを防ぎます。

COMMITされた時点で、トランザクションの衝突が発生していないかがチェックされることになります。

When a BEGIN CONCURRENT transaction is committed, the system checks whether or not any of the database pages that the transaction has read have been modified since the BEGIN CONCURRENT was opened. In other words – it asks if the transaction being committed operates on a different set of data than all other concurrently executing transactions. If the answer is “yes, this transaction did not read or modify any data modified by any concurrent transaction”, then the transaction is committed as normal.

BEGIN CONCURRENTトランザクションがコミットされると、システムはBEGIN CONCURRENTがオープンされてから、トランザクションが読み込んだデータベースのページが変更されたかどうかをチェックします。言い換えると、コミットされるトランザクションが、他のすべての同時実行トランザクションとは異なるデータ集合を操作しているかどうかを確認します。
その答えが 「はい、このトランザクションは同時実行中のトランザクションによって変更されたデータを読み込んだり変更したりしませんでした」であれば、そのトランザクションは通常通りコミットされます。

もしトランザクションの衝突が発生していた場合、ロールバックのみが可能です。

Otherwise, if the transaction does conflict, it cannot be committed and an SQLITE_BUSY_SNAPSHOT error is returned. At this point, all the client can do is ROLLBACK the transaction.
If SQLITE_BUSY_SNAPSHOT is returned, messages are output via the sqlite3_log mechanism indicating the page and table or index on which the conflict occurred. This can be useful when optimizing concurrency.

そうでない場合、トランザクションが衝突していればコミットできず、SQLITE_BUSY_SNAPSHOTエラーが返されます。この時点でクライアントにできることは、トランザクションをロールバックすることだけです。
SQLITE_BUSY_SNAPSHOTが返された場合、sqlite3_logメカニズムを通じて、競合が発生したページとテーブルまたはインデックスを示すメッセージが出力されます。これは同時実行を最適化する際に有用です。

このCOMMIT処理はつねに1つずつ直列化されて行われます。

In order to serialize COMMIT processing, SQLite takes a lock on the database as part of each COMMIT command and releases it before returning. At most one writer may hold this lock at any one time. If a writer cannot obtain the lock, it uses SQLite’s busy-handler to pause and retry for a while:

COMMIT処理を直列化するために、SQLiteは各COMMITコマンドの一部としてデータベースに対するロックを取り、戻る前にロックを解放します。一度にこのロックを保持できるライターは1つまでです。ライターがロックを取得できない場合、SQLiteのbusy-handlerを使用して一時停止し、しばらく再試行します:

同時書き込みを最大化するには?

アプリケーション開発者としてはこの同時書き込み機能を活用するために、できるだけトランザクションの衝突を起こさないように配慮するべきでしょう。

SQLiteでは、各テーブルと各インデックスは個別のb-treeとして格納され、それぞれが個別のデータベースページの集合に分散されているため以下の2つが言えると説明されています。

1)異なるテーブル・セットに書き込む2つのトランザクションが衝突することはない。

2)同じテーブルまたはインデックスに書き込む2つのトランザクションが衝突するのは、キー(主キーまたはインデックス行)の値がかなり近い場合だけである。

つまりテーブルが異なればページも異なるため、衝突することはなく、同じテーブルであってもキーの値が遠ければページが異なる可能性が高い、ということのようです。

SQLite 3での同時書き込みによるアプリケーションの高速化の恩恵を受けるために、今後はこれらを可能な範囲で配慮したデータベースのスキーマや格納する値などを慎重に設計するとよさそうです。

COMMENTS


Recommended

TITLE
CATEGORY
DATE
Docker DesktopとDocker Hubがシングルサインオンに対応。SAML 2.0と Azure Active Directoryをサポート
Docker
2022-01-20 12:23
米ガートナー「先進テクノロジーのハイプサイクル2024年」を発表。6Gや汎用人工知能は黎明期、プロンプトエンジニアリング、WebAssemblyは過度な期待のピーク
業界動向
2024-08-22 23:59
武蔵野赤十字病院、VMwareの仮想化基盤を刷新–デルが支援
IT関連
2024-09-19 17:07
NTT西ら、「大阪・関西万博」予定地で交通量予測モデルを実証
IT関連
2022-11-29 12:51
兵庫県神戸市、システム内製でコロナ電話対応を10分の1に 全国的なDXには仕様統一が重要
IT関連
2021-03-05 23:34
米国の転職者の確定拠出年金を集約するCapitalizeがシリーズAで13.1億円を調達
フィンテック
2021-02-16 14:27
仮想通貨のAnchorageが連邦銀行の認可を受けデジタル資産銀行に、約85.3億円の資金調達
フィンテック
2021-03-01 09:04
ECサイトでまたクレカ情報流出か 建築系ショップから2018年7月〜21年1月の間に4000件以上
セキュリティ
2021-07-21 01:06
eラーニングシステム「learningBOX」を提供する龍野情報システムが総額8800万円調達
IT関連
2022-01-29 11:14
マイクロソフト、データセンターのバーチャルツアー公開
IT関連
2021-04-22 06:29
マッチングアプリのプロフ写真は本物? AIで照合 「Tinder」新機能
ロボット・AI
2021-04-22 15:20
IBMプレジデントのホワイトハースト氏(元Red HatのCEO)が辞任
企業・業界動向
2021-07-06 13:52
OSSコミュニティーの4年後生存確率は50%超–NTTと九大が分析
IT関連
2023-12-06 06:38
デジタルトランスフォーメーション:バリューを最大化する予算配分を実現するためのヒント
IT関連
2021-08-10 05:31