BLOB (GA version) Usage and Notes (ja) #232
akirakw
announced in
Announcements
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
BLOB, CLOB 型の利用方法
Tsurugi 1.11.0 より、正式機能として BLOB, CLOB 型のカラムをサポートしました。
このドキュメントでは、BLOB, CLOB 型の利用方法と注意点について解説します。
Note
Tsurugi 1.10.0 およびそれ以前のバージョンでは、BLOB, CLOB 型は試験的機能 (Experimental Feature) として提供されていました。
試験的機能 における BLOB, CLOB 型の利用方法については、以下のドキュメントを参照してください。
用語について
本書では BLOB, CLOB 型の両方を扱う用語について、単に「BLOB...」と表記することがあります。
たとえば、以下のような用語が該当します:
これらの用語については、基本的には BLOB, CLOB 型の両方を扱う概念や機能として使用しています。
その他の用語についても、文中で特記しない限りは BLOB, CLOB 型の両方を扱うものとします。
BLOB, CLOB 型の特徴
BLOB, CLOB 型は、バイナリデータやサイズが大きな文字列データを格納するためのデータ型です。
Tsurugi はインメモリ型のデータベースであり、基本的には小さなデータを大量に処理することに最適化してデザインしています。
対して、BLOB, CLOB 型のデータ(以下「BLOBデータ」)は基本的に大きなデータであるため、Tsurugi はそれらのデータをメモリ上には保持せず、ファイルシステム上に保存することでメモリの使用量を削減しています。
上記のような関係で、BLOB, CLOB 型はほかのデータ型と比べて利用時の特性が異なる場合があります。
以下に例を挙げます:
=,<>,IN,GROUP BY,DISTINCTなど) や順序比較 (<,>,ORDER BY, インデックスキーとしての利用など) ができないなお、Tsurugi 上に記録した BLOBデータのファイルは、BLOBデータを含む行が参照されなくなった後に自動的に削除されます。
Tsurugi ではマルチバージョン並列性制御 (MVCC) 方式を採用しているため、
DELETE文等で行を削除しても即座にそのファイルが削除されるわけではありません。詳しくは BLOBのライフサイクル を参照してください。
BLOB, CLOB 型のデータ交換方法
BLOB, CLOB 型は上記の特徴から、クライアント・サーバ間でデータを交換する方法もほかのデータ型とは異なります。
Tsurugiでは、BLOBデータの交換方法として以下2つの転送モード(以下、BLOB転送モード) を提供しています:
Tsurugiが提供する各種クライアントは、Tsurugiに対するセッションの接続時にBLOB転送モードを指定することができます。
以下に、それぞれのBLOB転送モードの特徴を説明します。
リレーモード (relay mode)
リレーモードは、Tsurugiに組み込まれているgRPCサービス「BLOB中継サービス」を介してBLOBデータを交換する方式です。
リレーモードは、Tsurugiが提供する各種クライアントのデフォルトのBLOB転送モードとなっています。
BLOB中継サービスは、Tsurugiがファイルシステムとして保存して管理するBLOBデータをgRPCプロトコル上でクライアントに受け渡しするgRPCサービスです。
Tsurugiが提供する各種クライアントライブラリは、BLOB中継サービスと通信してBLOBデータをやりとりするAPI群を提供しており、アプリケーションはこれらのクライアントAPIを利用してBLOB, CLOB型を利用することができます。
リレーモードを利用する場合、その利用環境に応じて Tsurugiの設定 やクライアントの接続設定を適切に指定し、クライアント・サーバ間でBLOB中継サービスに対して通信が行えるようにする必要があります。
Important
Tsurugiの初期設定では、Tsurugiに組み込まれているgRPCサーバが無効となっているため、リレーモードが利用できないようになっています。
リレーモードを利用する場合には Tsurugiの設定 の説明に従いgRPCサーバを有効化した上で、必要に応じてその他の設定項目を適切に指定してください。
特権モード (privileged mode)
特権モードは、Tsurugiサーバが管理するファイルシステム上のBLOBデータをクライアントが直接読み書きする方式です。
実行環境に強い制約を受けるが性能が高く、通常はIPC接続を利用するクライアントから利用することを想定しています。
特権モードは、ローカルファイルシステムを介してBLOBデータを交換する方式であり、以下のような特徴があります:
特権モードを利用するには、その利用環境や権限に強い制約が生じます。具体的には、以下の条件を満たす必要があります:
tsurugidbプロセスが読み出し可能でなければならないtsurugidbプロセスが作成した BLOBデータのファイルを、クライアントが読み出し可能でなければならないtsurugi.iniのdatastoreセクション、log_locationで指定したディレクトリ配下にblobというフォルダを作成し、その配下に個別のファイルを配置します特権モードを利用する場合、上記の条件を満たすようなクライアントアプリケーションの実装や実行環境の構築を行う必要があります。
Tsurugiの設定
BLOB, CLOB 型の利用に関連する Tsurugiの構成定義ファイル (tsurugi.ini) の設定項目のうち、ここでは特に初期設定として重要な項目について説明します。すべての構成定義ファイルの設定項目については、以下のドキュメントを参照してください。
リレーモードに関連する設定項目
[grpc_server]セクションenabled(デフォルト値:false)trueに設定する必要があります。listen_address(デフォルト値:0.0.0.0:52345)endpointの値を合わせて適切に設定する必要があります。endpoint(デフォルト値:dns:///localhost:52345)secure(デフォルト値:false)trueに設定した場合、さらに設定項目fullchain_crtとserver_keyに適切なフルチェイン証明書とサーバ秘密鍵のファイルパスを指定する必要があります。[blob_relay]セクション特権モードに関連する設定項目
Note
以下の設定は通常変更する必要はありません。
[stream_endpoint]セクションallow_blob_privileged(デフォルト値:false)[ipc_endpoint]セクションallow_blob_privileged(デフォルト値:true)Docker環境での利用
Tsurugi Dockerイメージでは、リレーモードを利用するための設定項目がデフォルトで有効になっています。
Tsurugi Dockerイメージのデフォルト設定でリレーモードを利用する場合は、Docker上で動作するBLOB中継サービスの待ち受けポート
52345をホスト側にマッピングしてDockerコンテナを起動します。詳しくは、以下のドキュメントを参照してください。
SQL
SQLからBLOB, CLOB 型を利用する方法について説明します。
BLOB, CLOB 型の列を定義する
BLOB, CLOB 型の列を定義するには、
CREATE TABLE文のカラム定義に、それぞれBLOBまたはCLOBを指定します。なお、
BLOB,CLOB型にはそれぞれ別名があります:BINARY LARGE OBJECTCHARACTER LARGE OBJECTCHAR LARGE OBJECTBLOB, CLOB 型の型変換
BLOB, CLOB 型はCASTにより以下の型変換が可能です。
型変換に詳しくは、以下のドキュメントを参照してください。
クライアントツール・API
各種クライアントツール・APIを利用して BLOB, CLOB 型を操作する方法について説明します。
tgsql(SQLコンソール)tgsqlコマンドを利用して BLOB, CLOB 型のデータを取得するには、以下のように記述します:注意点として、
SELECT文の結果セットに含まれる BLOB, CLOB 型のデータを取得するには、そのSELECT文を実行したトランザクションが終了するまでの間に実施する必要があります。トランザクションが終了すると、その結果セットに含まれる BLOB, CLOB 型のデータは利用不可能になります。
tgsqlのBLOB, CLOB 型に対する機能の詳細については、以下のドキュメントを参照してください。Tip
現時点では
tgsqlコマンド経由でファイルを入力として BLOB, CLOB 型のデータを直接登録する機能は提供していません。リテラルによるBLOB, CLOB 型のデータ登録や、他のデータ型からキャストしてBLOB, CLOB 型のデータを登録することは可能です。
tgsqlでのBLOB転送モードの指定tgsqlコマンドでBLOB転送モードを指定するには、--lob-transfer-typeオプションを利用します。--lob-transfer-typeオプションの詳細については、以下のドキュメントを参照してください。Iceaxe (高レベル Java API)
Iceaxe で BLOB転送モードを設定する
Iceaxe では、セッション接続時のオプションでBLOB転送モードに関する設定を行います。
リレーモードの設定例:
Iceaxe で BLOB, CLOB 型の列にデータを挿入する
Iceaxe が提供するAPIを利用して BLOB, CLOB 型の列にデータを挿入するには、以下のようなプログラムを作成します:
Iceaxe で BLOB, CLOB 型の列を参照する
Iceaxe が提供するAPIを利用して BLOB, CLOB 型の列を参照するには、以下のようなプログラムを作成します:
Iceaxe の BLOB, CLOB 型に対する機能の詳細については、以下のドキュメントを参照してください。
Tsubakuro/Java (低レベル Java API)
Tsubakuro/Java で BLOB転送モードを設定する
Tsubakuro/Java では、接続セッションに対してBLOB転送モードに関する設定を行います。
リレーモードの設定例:
特権モードの設定例:
Tsubakuro/Java で BLOB, CLOB 型の列にデータを挿入する
Tsubakuro/Java が提供するAPIを利用して BLOB, CLOB 型の列にデータを挿入するには、以下のようなプログラムを作成します:
Tsubakuro/Java で BLOB, CLOB 型の列を参照する
Tsubakuro/Java が提供するAPIを利用して BLOB, CLOB 型の列を参照するには、以下のようなプログラムを作成します:
ユーティリティメソッド
TransactionインターフェースではBLOBを扱ういくつかのユーティリティメソッドも提供しています。Tsubakuro/Java のAPI詳細については、以下のJavadocを参照してください。
Tsurugi JDBC
Tsurugi JDBC で BLOB転送モードを設定する
Tsurugi JDBC では、JDBC URLやプロパティー等でBLOB転送モードに関する設定を行います。
リレーモードの設定例:
Note
JDBC URLのクエリー文字列では、
:や/はURLエンコードする必要があります。Tsurugi JDBC で BLOB, CLOB 型の列にデータを挿入する
Tsurugi JDBCで BLOB, CLOB 型の列にデータを挿入するための特別なAPIはありません。一般的なJDBCと同様に、以下のようなプログラムを作成します:
Tsurugi JDBC で BLOB, CLOB 型の列を参照する
Tsurugi JDBCで BLOB, CLOB 型の列を参照するための特別なAPIはありません。一般的なJDBCと同様に、以下のようなプログラムを作成します:
Tsurugi JDBC のBLOB, CLOB 型に対する機能の詳細については、以下のドキュメントを参照してください。
Tsubakuro/Rust (Rust API)
Tsubakuro/Rust で BLOB転送モードを設定する
Tsubakuro/Rust では、セッション接続時のオプションでBLOB転送モードに関する設定を行います。
リレーモードの設定例:
Note
Tsubakuro/Rust ではBLOB中継サービスのエンドポイントで
dns:///は使用できません。http://に置き換えてください。Tsubakuro/Rust で BLOB, CLOB 型の列にデータを挿入する
Tsubakuro/Rust が提供するAPIを利用して BLOB, CLOB 型の列にデータを挿入するには、以下のようなプログラムを作成します:
Tsubakuro/Rust で BLOB, CLOB 型の列を参照する
Tsubakuro/Rust が提供するAPIを利用して BLOB, CLOB 型の列を参照するには、以下のようなプログラムを作成します:
Tsubakuro/Rust の BLOB, CLOB 型に対する機能の詳細については、以下のドキュメントを参照してください。
Tsurugi Python DB-API
Tsurugi Python DB-API は、BLOB中継サービスのみ利用できます。
したがって、BLOB転送モードを設定することはできません。
リレーモードの設定例:
BLOB中継サービスのエンドポイントを指定する場合は、セッション接続時のConfigで指定します。
Note
Tsurugi Python DB-API ではBLOB中継サービスのエンドポイントで
dns:///は使用できません。http://に置き換えてください。Tsurugi Python DB-API で BLOB, CLOB 型の列にデータを挿入する
Tsurugi Python DB-API が提供するAPIを利用して BLOB, CLOB 型の列にデータを挿入するには、以下のようなプログラムを作成します:
Tsurugi Python DB-API で BLOB, CLOB 型の列を参照する
Tsurugi Python DB-API で BLOB, CLOB 型の列を参照するための特別なAPIはありません。
Tsurugi Python DB-API の BLOB, CLOB 型に対する機能の詳細については、以下のドキュメントを参照してください。
その他の機能
特権モードにおけるファイルパスの変換
Iceaxe, Tsubakuro/Java 等のクライアントライブラリでは、特権モードでクライアントとサーバ間でファイルの交換を行う際にファイルパスを自動的に変換する機能を提供しています。これにより、クライアントとサーバで異なるファイルシステム構成となっている場合でも、特権モードを利用して BLOBデータの交換が可能になります。
/opt/tsurugi/var/data/log/blob上に BLOB ファイルが配備されている際、それをクライアントはC:\tmp\tsurugi\blobに読み替えてアクセスすることが可能です。Iceaxe
Iceaxe では以下のようにファイルパスの変換ルールを指定します。
Tsubakuro/Java
Tsubakuro/Java では以下のようにファイルパスの変換ルールを指定します。
Tsurugi JDBC
Tsurugi JDBC では以下のようにファイルパスの変換ルールを指定します。
Tsubakuro/Rust
Tsubakuro/Rust では以下のようにファイルパスの変換ルールを指定します。
Tsurugi Python DB-API
Tsurugi Python DB-API は特権モードに対応していないため、ファイルパスの変換ルールを指定することはできません。
トラブルシューティング
ここではBLOB, CLOB 型の利用時に発生する代表的なエラーについて説明します。
リレーモード利用時のエラー
CoreServiceException: the requested blob transfer method (RELAY) is unavailableリレーモードの利用時に以下のエラーが発生する:
この場合、以下の点を確認してください。
[grpc_server]セクションのパラメータenabledがtrueに設定されているか[blob_relay]セクションのパラメータenabledがtrueに設定されているかIOException: Blob relay service is unavailable on dns:...リレーモードの利用時に以下のようなエラーが発生する:
この場合、様々なネットワーク構成に起因する問題が考えられます。例外メッセージを参考に、以下の点などを確認してください。
[grpc_server]セクションのパラメータendpointが クライアントから接続可能な値に設定されているか。特権モード利用時のエラー
CoreServiceException: the requested blob transfer method (PRIVILEGED) is unavailable特権モードの利用時に以下のエラーが発生する:
この場合、以下の点を確認してください。
[stream_endpoint]セクションのallow_blob_privilegedがtrueに設定されているか[ipc_endpoint]セクションのallow_blob_privilegedがtrueに設定されているかBlobException: Privileged upload from [InputStream|Reader] is not supported特権モードの利用時に以下のエラーが発生する:
特権モード利用時に、クライアントAPIによっては固有の制約が設定されている場合があります。
上記のエラーは Tsubakuroを利用して特権モードでBLOBデータをサーバに送信する際に、
InputStreamやReaderインターフェースを利用して送信しようとした場合に発生します。Tsubakuroでは、特権モードでBLOBデータをサーバに送信する際にはローカルファイルシステム上のファイルを指定して送信する必要があります。[CoreServiceException|BlobException]: tsurugidb failed to receive BLOB file in privileged mode ...特権モードの制約である、クライアント・サーバそれぞれから見て同一のファイルシステム上の、同一のパスでファイルにアクセスできるという条件が満たされない場合に発生します。
クライアントからBLOB データの登録(INSERT文など)に失敗する例 - クライアントが指定したBLOB データのファイルパスがサーバ上で見つからなかった場合:
クライアントからBLOB データを参照(SELECT文実行後、BLOB データの取得)に失敗する例 - サーバが管理するBLOB データのファイルパスがクライアント上で見つからなかった場合:
また、クライアントから指定するファイルパスにはディレクトリやシンボリックリンクを指定することはできません:
高度な話題
特権モードのセキュリティ
特権モードは、ファイルシステムを介して BLOBデータを交換するため、「サーバの
tsurugidbプロセスの権限を利用して、本来アクセスできないはずのファイルを読めてしまう」というセキュリティ上の問題があります。上記に対応するため、特権モードに対して「許可リスト」の導入を予定しています。
これは、サーバが BLOBデータのファイルパスを受け取った際、許可リストに含まれないディレクトリの配下であれば、それを拒否するという仕組みです。
これにより、「本来アクセスできないはずのファイルを読めてしまう」という問題の大半を解消します。
なお、リレーモードではサーバ側のファイルシステムを直接操作することはないため、この問題は発生しません。
BLOBのライフサイクル
BLOBデータは、クライアントからの要請 (例: SQLのプレースホルダに対する指定) によって作成され、Tsurugi 内に保存します。
このとき、ログ (WAL) データを格納しているディレクトリ (
datastore.log_location) の下にblobというディレクトリを作成し、その配下に BLOB ごとに個別のファイルを作成します。BLOBデータは、不要になった際にガベージコレクション機構によって自動的に削除されます。
これはつまり、
DELETE文やDROP TABLE文を実行しても、即座に BLOBデータが削除されるわけではありません。具体的には、次の 3 つのステップで削除が行われます:
DELETE文等を実行)上記のような仕組みで BLOBデータを管理しているため、BLOBデータを取得するには、その行を取得したトランザクション内で、 BLOBデータを取り出す必要があります。
なぜなら、当該トランザクションが終了すると、2番目の手順によってガベージコレクションの境界が替わり、当該 BLOBデータが削除される可能性があるためです。
なお、ガベージコレクションを実際に実行するには、以下のいずれかの操作が必要です:
バックアップ・リストアについて
バックアップ・リストアにおいて BLOB, CLOB を含むテーブルデータを対象とする場合、上述の
blobディレクトリの配下で管理している BLOB ファイルもバックアップ・リストアの対象となります。tgctl backup createコマンドでバックアップを作成する際、BLOB, CLOB ファイルもバックアップに含まれます。tgctl restore backupコマンドでバックアップをリストアする際、バックアップに含まれる BLOB, CLOB ファイルもリストアされます。Beta Was this translation helpful? Give feedback.
All reactions