HiveテーブルをIcebergテーブルに移行するプロシージャの実装
migrateプロシージャのシンタックス
Trinoバージョン411でIcebergコネクタに追加されたmigrateプロシージャについて解説します。このプロシージャは、既存のHiveテーブル(ORC、Parquet、Avroフォーマット)をIcebergテーブルに変換します。
CALL iceberg.system.migrate(
schema_name => 'testdb',
table_name => 'customer_orders',
recursive_directory => 'true');
このプロシージャは3つの引数をサポートしています。
名前 | 必須 | 説明 |
---|---|---|
schema_name | Required | スキーマ名 |
table_name | Required | テーブル名 |
recursive_directory | Optional | ディレクトリを再帰的に走査するか |
recursive_directoryの設定可能な値はtrue、false、failです。
- true: ディレクトリを再帰的に検索する
- false: 直下のディレクトリのファイルのみを検索する
- fail: テーブルまたはパーティションのロケーション配下にネストされたディレクトリが存在する場合に例外をスローします。failがデフォルトです。
migrateプロシージャの実装
次に、このプロシージャの実装の詳細について説明します。
1. Hiveテーブルの定義に基づいてIcebergのスキーマオブジェクトを生成する
引数で指定されたテーブルをHive Metastore (HMS)やGlueから取得します。
Hiveテーブルの情報からIcebergを作成するのに必要なSchemaやPartitionSpecのオブジェクトを生成します。
2. Hiveテーブルのファイルをリストする
非パーティションテーブルであればテーブルのパス、パーティションテーブルであれば各パーティションのディレクトリ配下を見ていきます。
ParquetやORCファイルはフッターからMetrics(行数、カラム毎のサイズ、非NULLの数、NULLの数、NaNの数、上限と下限)を算出します。Avroでは行数のみ算出します。
次に既存のHiveのデータファイルからDataFileのオブジェクトを生成します。Trinoでは以下のようなヘルパーメソッドを使っています。
public static DataFile buildDataFile(String path, long length, Optional<StructLike> partition, PartitionSpec spec, String format, Metrics metrics)
{
DataFiles.Builder dataFile = DataFiles.builder(spec)
.withPath(path)
.withFormat(format)
.withFileSizeInBytes(length)
.withMetrics(metrics);
partition.ifPresent(dataFile::withPartition);
return dataFile.build();
}
3. トランザクションを開始する
Icebergテーブルを新規作成するTransactionを作成し、前のステップで生成したDataFileのリストを追加していきます。この時点で、Icebergのメタデータファイルは生成されていますが、メタストア上ではまだHiveテーブルのままです。
Table table = transaction.table();
AppendFiles append = table.newAppend();
dataFiles.forEach(append::appendFile);
append.commit();
4. メタストアの情報を更新する
Trinoやその他のクエリエンジンはメタストア上の情報を見てそのテーブルフォーマットを判断しています。このステップでtable_type
テーブルプロパティにICEBERG
を設定し、メタストアの情報を更新します。
逆に言い換えるとIcebergテーブルを元に戻したい場合はtable_type
プロパティを削除してしまえば、Hiveテーブルとしてアクセス可能です。
5. トランザクションをコミットする
最後にトランザクションをコミットします。このコミットでIcebergのアーキテクチャでよく出てくる”最新のメタデータファイルへのポインタ”となるmetadata_location
テーブルプロパティが設定され、Icebergテーブルへのアクセスが可能となります。
Discussion