HN 日本語サマリー

← 一覧へ戻る
プログラミング

MySQL向けの新しく書き込み・スペース最適化されたストレージエンジンが登場

A new write and space optimized storage engine for MySQL is here (tidesdb.com)

24 pointsby alexpadula4 コメント

要約

TidesDBは、MySQL向けの新しい外部プラグインストレージエンジンとして利用可能になりました。このエンジンは、書き込みとスペースの最適化に優れ、読み取り性能も高いのが特徴です。圧縮、値の分離、LSMツリーの形状設定、耐久性、暗号化などの豊富な設定オプションを備え、MVCCによる楽観的同時実行制御を提供します。ベンチマークでは、特に書き込みと削除のワークロードにおいて、InnoDBと比較して大幅なパフォーマンス向上とディスクI/O削減を示しました。

全文翻訳

TidesDBがMySQL v9、v267で利用可能になりました。読み取り時間9分 Charmain Jansen van Rensburg著 Alex Gaetano Padula 2026年10月5日公開 おそらく多くの人は知らないかもしれませんが、元々TideSQLはMySQLのフォークとして始まり、TidesDBライブラリをプラグインとして実装し、その強力なストレージエンジンをMySQLユーザーに提供することを目指していました。しかし、当時のMySQLコミュニティではそれを実現する方法がなく、そのため当初の計画は変更されました。それからほぼ1年が経過し、多くのことが変わりました。TidesDBをMySQLで利用可能にするための提案が行われ、それが実現しました。TidesDBは、素晴らしい機能セットと今後追加される機能を持つ、外部プラグインストレージエンジンとしてMySQLで利用可能になりました。 現在、TidesDBプラグインエンジンにアクセスする主な方法は、リポジトリ内のinstall.shスクリプトを使用することです。このスクリプトは、ビルドを指定するか、インストーラーにバンドルをビルドさせるかのいずれかを行います。将来的には、ユーザーにとってより簡単にする予定であり、関連当事者と協議中です。 TidesDBは、書き込みとスペースの最適化に優れたストレージエンジンであり、読み取りにも十分対応できます。これはフォークではなくプラグインです。標準のMySQLを実行し、エンジンをロードすると、TidesDBテーブルは同じサーバー上のInnoDBテーブルの隣に配置できます。TideSQL-MySQL v2.0.0はTidesDB v10.1.1とペアリングされ、MySQL v9.7.0およびv26.7.0でテストされています。 INSTALL PLUGIN TIDESDB SONAME 'ha_tidesdb.so'; CREATE TABLE events (id BIGINT PRIMARY KEY, body TEXT) ENGINE=TIDESDB; MySQLにはエンジン固有のCREATE TABLE構文がないため、テーブルはENGINE_ATTRIBUTE内のTidesDBオプションを名前で指定します。これはサーバーが読み取らずにエンジンに渡すJSONオブジェクトです。エンジンがこれらの名前を定義するため、エンジンがチェックし、スペルミスのあるオプションは保存されて無視されるのではなく、ステートメントを失敗させます。すべてのオプションには、セッション変数tidesdb_default_*が背後にあるため、ポリシーを一度設定すれば、すべてのCREATE TABLEがそれを継承できます。テーブルが名前を指定しないものは、作成時に解決され、そのまま保持されます。 CREATE TABLE archive (id INT PRIMARY KEY, data TEXT) ENGINE=TIDESDB ENGINE_ATTRIBUTE='{"compression": "ZSTD", "bloom_fpr": 50}'; 圧縮はデフォルトで有効になっています。選択肢はNONE、SNAPPY、LZ4、ZSTD、LZ4_FASTで、デフォルトはLZ4です。ZSTDは、速度よりも圧縮率を重視する場合に使用します。 大きな値はコンパクションから除外されます。各SSTableには独自のキーログがあり、データベース全体で1つのセグメント化された値ログを共有します。tidesdb_value_separation_threshold以上の値は値ログに送られ、キーログにはポインタが残ります。これにより、後続のマージでは値ではなくポインタが書き直されます。スキャン時に1行あたり1つの値ログ読み取りが発生するため、マージよりもスキャンがはるかに多いテーブルでは、{"keep_values_inline": true}を設定して、値のサイズに関係なくすべての値をキーログに保持できます。 LSMの形状は自由に設定できます。level_size_ratioは各レベルが前のレベルよりどれだけ大きいかを示し、min_levelsは最小深度、l1_file_count_triggerはコンパクションでマージされる前にレベル1に集まるSSTableの数です。選択できるコンパクションポリシーはありません。エンジンはツリーの状態から、フルプリエンプティブマージ、分割マージ、パーティションマージの中から選択します。削除が多いテーブルの場合、tombstone_density_triggerは、設定した比率を超えてトームストーンが増加したレベル1SSTableのコンパクションをエスカレートさせます。 CREATE TABLE tuned (id INT PRIMARY KEY, v VARCHAR(200)) ENGINE=TIDESDB ENGINE_ATTRIBUTE='{"level_size_ratio": 8, "min_levels": 3, "l1_file_count_trigger": 4}'; 耐久性はtidesdb_memtable_sync_modeという1つの設定で、すべてのコミットを管理します。なぜなら、すべてのテーブルがライブラリのライトアヘッドログを共有しているからです。FULLはデフォルトで、コミットされた書き込みがデバイスに到達し、電源喪失後も生存することを意味します。INTERVALは各コミットをオペレーティングシステムに渡し、間隔内にデバイスに到達するため、プロセスクラッシュでは何も失われず、マシンクラッシュでは最大でそのウィンドウ分が失われます。NONEはコミット時には何も行わず、確認されたコミットはバッファに残り、後続のバッチで書き出されるまで、プロセスクラッシュで失われる可能性があります。NONEは再構築可能なデータ用です。 行は、テーブルレベル、行レベル、またはセッションレベルで自動的に期限切れになり、その順序で解決されます。保存時の暗号化は、2層のキー配置で各行ごとに行われるため、マスターキーのローテーションは行データに影響しません。暗号化されたテーブルの行は、ライブラリがそれらを見る時点ですでに暗号化されているため、その列ファミリーでは圧縮が強制的にオフになります。一方、セカンダリインデックスは、暗号化されていない比較可能なキーを保持し、選択したアルゴリズムを維持します。 本日動作するその他の機能: FULLTEXTインデックス(自然言語およびブールモード、BM25ランキング、ストップワード、ブレンド文字) 外部キー(エンジン内で強制、ON DELETEおよびON UPDATEでCASCADE、SET NULL、RESTRICT、自己参照) 空間インデックス、生成列、JSONベクトル列(保存および読み取りは可能ですが、それらに対する類似性検索はありません) インスタントADD COLUMNおよびDROP COLUMN(パックされた行は自己記述ヘッダーを持つため、デシリアライザーは以前のスキーマで書き込まれた行に適応します) ANALYZE TABLEを実行せずにオプティマイザーが使用できる統計情報(テーブルにデータが投入された最初の要求時にサンプリングされます) オンラインバックアップおよびチェックポイント、およびツリーの動作状況を表示するSHOW ENGINE TIDESDB STATUS 同時実行性は楽観的MVCCです。悲観的行ロックはないため、ロック待機やチューニングが必要なロック待機デッドロックはありません。書き込み競合はステートメント内ではなくコミット時にER_ERROR_DURING_COMMIT (1180)として表示され、明示的なBEGIN ... COMMITを使用するアプリケーションは、REPEATABLE READ以上で再試行する必要があります。オートコミットステートメントはREAD COMMITTEDで実行され、ライブラリは書き込み-書き込みチェックを行いません。何も書き込まなかったトランザクションは競合しません。 同じサーバー上で、各エンジンがデフォルト設定のまま、8つのテーブル(それぞれ500万行)に対してsysbench 1.0.20を実行しました。標準からの唯一の2つの変更点は、READ COMMITTEDと耐久性モードであり、両エンジンで一致させているため、書き込みにおいてどちらも有利なパスを得られません。トランザクション/秒(24スレッド時、このボックスがピークに達した時点) ボックス: Intel i9-13900、オンラインで24スレッド、8 Pコア(5.3-5.6 GHz)+ 16 Eコア(4.2 GHz)、実行用に8 Pコアを分離Ubuntu 24.04.4 LTS (6.8.0-136-generic) 125.5 GiB DDR5、ECCなしNVMe Micron 7450、xfs、OSディスクとは別gcc 13.3.0 jemalloc(ライブラリおよびサーバー用) ワークロード TidesDB InnoDB ポイントセレクト 246,410 95,760 2.6x リードライト 5,993 2,989 2.0x インデックス更新 102,273 18,962 5.4x ライトオンリー 31,839 6,878 4.6x 削除 154,048 25,792 6.0x バイト数がその理由を示しています。これらは、いずれかのエンジンの独自の会計処理ではなく、/proc/diskstatsから取得されるため、両方ともエンジンの下で同じ方法で測定され、各実行の後にはセトルが行われ、エンジンが遅延させた書き込みもその実行に課金されます。 ワークロード TidesDB InnoDB インデックス更新 3,000 B 56,461 B 19x less ライトオンリー 9,290 B 155,398 B 17x less リードライト 11,196 B 192,741 B 17x less 削除 916 B 42,910 B 47x less 操作あたりのデバイスへの書き込みバイト数。 データセットは約8 GBで、256 MBのブロックキャッシュと256 MBのTidesDB出荷時メモリテーブル、およびInnoDBの128 MBバッファプールに対して行われるため、どちらのエンジンもメモリに保持していません。ランダムな行のInnoDB更新では、通常は常駐していない16 KBのページを見つけ、読み込み、変更し、ダブルライトバッファを介してredoの上に16 KBすべてを書き戻す必要があります。TidesDBは数百バイトを追加し、後で整理します。標準のsysbenchセットのいずれも値ログに触れません。sbtestの行は約188バイトで、値は1024バイトを超えるとログに記録されるため、上記のすべてのワークロードはキーログ内に収まります。大きな値は設計が対象としているケースであるため、4 KBのテキスト列を持つ200,000行のテーブル4つに対して別のスクリプトを実行しました。フィールド名と単語の小さな語彙で構築されているため、ランダムな数字のようにではなく、ログ行やJSONドキュメントのように圧縮されます。3つの構成があり、3番目はkeep_values_inlineが設定されたTidesDBで、すべての値をキーログに保持しますw