FileLog では、次のことができます。
- ログファイルをサブスクライブする。
- サブスクライブしたログファイルに追記された新しいレコードを処理する。
テーブルの作成
path_to_logs– サブスクライブするログファイルのパス。ログファイルを含むディレクトリへのパス、または単一のログファイルへのパスを指定できます。なお、ClickHouse で指定できるのはuser_filesディレクトリ内のパスのみです。format_name- レコードのフォーマット。FileLog はファイル内の各行を個別のレコードとして処理するため、すべてのデータフォーマットがこれに適しているわけではありません。
poll_timeout_ms- ログファイルから 1 回pollする際のタイムアウト。デフォルト: stream_poll_timeout_ms。poll_max_batch_size— 1 回のpollで取得するレコードの最大数。デフォルト: max_block_size。max_block_size—pollの最大バッチサイズ (レコード数) 。デフォルト: max_insert_block_size。max_threads- ファイルを解析する最大スレッド数。デフォルトは 0 で、この場合は max(1, physical_cpu_cores / 4) が使用されます。poll_directory_watch_events_backoff_init- ディレクトリ監視スレッドの初期スリープ値。デフォルト:500。poll_directory_watch_events_backoff_max- ディレクトリ監視スレッドの最大スリープ値。デフォルト:32000。poll_directory_watch_events_backoff_factor- バックオフの進み方。デフォルトは指数関数的です。デフォルト:2。handle_error_mode— FileLog engine のエラー処理方法。設定可能な値: default (メッセージの解析に失敗した場合は例外がスローされます) 、stream (例外メッセージと生のメッセージが仮想カラム_errorおよび_raw_messageに保存されます) 。
説明
配信されたレコードは自動的に追跡されるため、ログファイル内の各レコードは一度しかカウントされません。SELECT はレコードの読み取りにはあまり適していません (デバッグ用途を除く) 。各レコードは一度しか読み取れないためです。より実用的なのは、materialized view を使ってリアルタイムのストリームを作成することです。そのためには、次のようにします。
- エンジンを使用して FileLog テーブルを作成し、それをデータストリームとして扱います。
- 必要な structure を持つテーブルを作成します。
- エンジンからのデータを変換し、あらかじめ作成したテーブルに格納する materialized view を作成します。
MATERIALIZED VIEW をエンジンに接続すると、バックグラウンドでデータの収集が開始されます。これにより、ログファイルからレコードを継続的に受け取り、SELECT を使って必要なフォーマットに変換できます。
1 つの FileLog テーブルには、必要な数だけ materialized view を持たせることができます。これらはテーブルから直接データを読み取るのではなく、新しいレコードを block 単位で受け取ります。そのため、詳細度の異なる複数のテーブルに書き込むことができます (グループ化と aggregation を行うもの/行わないもの) 。
例:
ALTER を使用してターゲットテーブルを変更する場合は、ターゲットテーブルとビューのデータに不整合が生じるのを避けるため、materialized view を無効にすることを推奨します。
仮想カラム
_filename- ログファイル名。データ型:LowCardinality(String)._offset- ログファイル内のオフセット。データ型:UInt64.
handle_error_mode='stream' の場合に追加される仮想カラム:
_raw_record- 正常にパースできなかった生のレコード。データ型:Nullable(String)._error- パース失敗時に発生した例外メッセージ。データ型:Nullable(String).
_raw_record と _error の仮想カラムに値が入るのは、パース中に例外が発生した場合のみです。メッセージが正常にパースされた場合、これらは常に NULL になります。
データの永続性
FileLog エンジンは、チャンクに対応する挿入がコミットされる前に、そのチャンクまで読み取ったオフセットを記録します。そのため、サーバーが中断されると、記録されたオフセットがターゲットテーブルに到達したデータより先に進む可能性があります。再起動時には、各ログファイルはメタデータディレクトリに記録されたオフセットから読み取りを再開するため、それらの行が再読み込みされることはありません。エラーは発生せずにデータが失われ、count() が単に小さくなります。通常のプロセス障害だけでもこの問題は発生し、電源断は必要ありません。これは、ターゲットパートの書き込みがまだ完了していない間にオフセットがメタデータファイルへ記録され、そのファイルが所定の場所へリネームされるためです。
OS page cache が失われると、すでにターゲットテーブルへ書き込まれたデータも失われる可能性があります。たとえば、デバイスレベルの電源断や、不適切なホストまたはカーネルのリセットが該当します。オフセットを保持するメタデータファイル自体も、ファイルまたはそのディレクトリに対して fsync を実行せずに書き込まれるため、それ自体の永続性も保証されません。
メッセージブローカーエンジンとは異なり、ターゲットを先に永続化しても FileLog をこの問題から保護することはできません。オフセットは、対応する挿入が完了する前に読み取りパイプライン内から記録されるため、ターゲットの MergeTree テーブルで fsync_after_insert = 1 を設定しても、オフセットが進む前に挿入されたパートの永続性を確立することはできません。FileLog の消費は、ローカルファイルをベストエフォートで追尾するものとして扱ってください。行を一切失えない場合は、消費したデータがターゲット内で検証されるまでソースログファイルを保持し、必要に応じて再度消費できるようにします。テーブルを削除して再作成すると、記録されたオフセットが破棄され、ファイルは先頭から再読み込みされます。