Skip to main content
VillageSQL の拡張機能アーキテクチャを理解することで、拡張機能の作成時に問題のデバッグやパフォーマンスの最適化が行いやすくなります。 拡張機能の作成プロセスはシンプルです。対応する SDK を使用して C++ または Rust の関数を書き、共有ライブラリにコンパイルし、マニフェストと共に .veb ファイルにパッケージ化します。INSTALL EXTENSION を実行すると、VillageSQL はライブラリを読み込み、登録コードを呼び出し、関数を即座に SQL として利用可能にします。これはサーバーに組み込まれているかのように、あらゆるクエリから呼び出すことができます。サーバーの再起動は不要です。このページの残りの部分では、このプロセスの各ステップがどのように動作するかを説明します。

用語

  • VEB (VillageSQL Extension Bundle) - マニフェスト、ライブラリ、メタデータを含む tar アーカイブ形式の .veb ファイル
  • VEF (VillageSQL Extension Framework) - 拡張機能の作成に使用する C++ および Rust 用 SDK
  • VDF (VillageSQL Defined Function) - VEF 経由で登録される関数 — C++ では VEF_GENERATE_ENTRY_POINTS()、Rust では extension! マクロを使用

VDF 関数の検索

VDF は修飾付きおよび修飾なしの関数呼び出しの両方をサポートします:
解決順序:
  1. システム関数(MySQL 組み込み)
  2. UDF(CREATE FUNCTION ... SONAME による従来の MySQL ユーザー定義関数)
  3. VDF(拡張機能関数)- その名前の関数がちょうど 1 つ存在する場合のみ
  4. ストアド関数(CREATE FUNCTION で作成)
複数の拡張機能が同じ名前の関数を登録している場合、修飾なしの呼び出しは曖昧になるため、完全修飾名(extension_name.function_name())を使用する必要があります。 パフォーマンス: ホットパスでは、解決チェーンをスキップして拡張機能関数を直接呼び出すため、修飾付き呼び出し(extension_name.function_name())を使用してください。

VEB ファイル形式

VillageSQL の拡張機能は .veb(VillageSQL Extension Bundle)ファイルとして配布されます。これは以下を含む tar アーカイブです:

manifest.json スキーマ

  • name: SQL で使用される拡張機能名(lowercase_with_underscores)と一致する必要があります
  • version: セマンティックバージョニング(MAJOR.MINOR.PATCH)
  • description, author, license: オプションのメタデータ

拡張機能のライフサイクル

インストールフロー

ロールバック: どのステップでも失敗した場合、すべての変更が取り消され、.so がアンロードされます。 シンボルの分離: 拡張機能は RTLD_LOCAL フラグで読み込まれ、ある拡張機能のシンボルが他の拡張機能のシンボルと競合しないようにします。これにより、複数の拡張機能が共通のライブラリ名や関数名を使用した場合でも、名前衝突を防ぎます。
veb_dir システム変数は、.veb 拡張機能ファイルが保存されるディレクトリを指します。

アンインストールフロー

依存関係の防止: テーブルの列が拡張機能のカスタム型を使用している場合、アンインストールできません。

展開ディレクトリ構造

VillageSQL は複数のバージョンをサポートするために、.veb ファイルを MySQL データディレクトリに展開します:
なぜ SHA256 ディレクトリなのか?
  • 上書きせずに新しいバージョンをテストできる
  • ロールバックを可能にする
  • 「同じバージョン、異なるコード」を防ぐ
クリーンアップ: 孤立した SHA256 ディレクトリはサーバー再起動時に削除されます。

Victionary キャッシュレイヤー

VictionaryClient は、O(log n) の検索のためにシステムメタデータのインメモリキャッシュを維持します。

キャッシュ操作

キャッシュ無効化: DDL 操作(INSTALL/UNINSTALL EXTENSION)中に自動実行されます。 メモリオーバーヘッド: エントリあたり約 100 バイト。

カスタム型システム

型解決

実装型

カスタム型は MySQL のストレージ型にマッピングされます:

並行処理とトランザクションの動作

スレッドセーフティモデル

拡張機能関数は行ごとの実行モデルで呼び出されます:
  • 行ごとの分離実行: 各関数呼び出しには独自の結果バッファが割り当てられます(設計上スレッドセーフ)
  • Prerun/Postrun フック: ステートメントごとのセットアップ/クリーンアップ、SQL ステートメントごとに 1 回呼び出されます
  • 分離の保証なし: 複数の接続が同時にあなたの関数を呼び出す可能性があります
  • ベストプラクティス: グローバル状態を避け、関数のパラメータと戻り値を使用してください
VillageSQL は拡張機能関数のスレッド分離を保証しません。グローバル変数や共有状態を使用する場合は、ミューテックスやロックで保護してください。

トランザクションの動作

拡張機能関数は以下のベストプラクティスに従う必要があります:
  • 可能な限りステートレスな関数を設計する
  • 関数内で永続的な副作用(ファイル書き込み、外部 API 呼び出し)を避ける
  • Prerun/postrun 状態を使用する場合は、適切にクリーンアップを処理する

パフォーマンスの考慮事項

最適化: 行ごとに作業を繰り返すのではなく、Prerun フックを使用して高コストなステートメントごとのセットアップをキャッシュしてください。

カスタム型のパフォーマンス


セキュリティとデバッグ

セキュリティモデル

信頼モデル: 拡張機能はサーバーのフル権限で実行されます。
  • サンドボックス化や権限システムはありません
  • 拡張機能は任意のファイルの読み取り、ネットワークへのアクセス、コードの実行が可能です
  • 信頼に関する影響: 信頼できるソースからの拡張機能のみをインストールしてください
インストールのセキュリティ: villagesql_extension_installer ユーザーとして実行されます(コンテキストスイッチ)。
詳細ログの有効化:
GDB デバッグ:
依存関係の確認:
一般的なエラー:
  • 未定義のシンボル: ldd(Linux)または otool -L(macOS)でライブラリの依存関係を確認してください
  • 共有オブジェクトを開けません: ライブラリの依存関係が存在し、正しくリンクされているか確認してください
  • VDF 呼び出し時のクラッシュ: NULL ポインタの処理を確認してください

次のステップ

拡張機能の作成

最初の拡張機能を作成する

システムリファレンス

システムテーブルとビュー

実装例

vsql_complex の実装を学ぶ

拡張機能の管理

モニタリングとトラブルシューティング