MySQL Shell 8.0  /  MySQL Shell ユーティリティ  /  パラレルテーブルインポートユーティリティ

このページは機械翻訳したものです。

8.4 パラレルテーブルインポートユーティリティ

MySQL Shell 8.0.17 で導入された MySQL Shell パラレルテーブルインポートユーティリティ util.importTable() は、大規模なデータファイルの MySQL リレーショナルテーブルへの高速データインポートを提供します。 このユーティリティは、入力データファイルを分析してチャンクに配布し、パラレル接続を使用してチャンクをターゲット MySQL サーバーにアップロードします。 このユーティリティは、LOAD DATA ステートメントを使用した標準のシングルスレッドアップロードよりも数回高速に大規模データインポートを完了できます。

パラレルテーブルインポートユーティリティを実行する場合、データファイルのフィールドと MySQL テーブルのカラムの間のマッピングを指定します。 LOAD DATA ステートメントの場合と同様に、フィールド処理および行処理のオプションを設定して、任意の形式でデータファイルを処理できます。 複数のファイルの場合、すべてのファイルは同じ形式である必要があります。 ユーティリティのデフォルト言語は、そのステートメントのデフォルト設定を使用して SELECT...INTO OUTFILE ステートメントを使用して作成されたファイルにマップされます。 ユーティリティには、CSV ファイル (DOS または UNIX システムで作成された)、TSV ファイルおよび JSON の標準データ形式にマップする事前設定済のダイアレクトもあり、必要に応じてフィールド処理および行処理オプションを使用してこれらをカスタマイズできます。 JSON データは、document-per-line 形式である必要があります。

パラレルテーブルインポートユーティリティが導入された後にいくつかの関数が追加されているため、最新バージョンの MySQL Shell を使用してユーティリティを完全に機能させてください。

入力前処理

MySQL Shell 8.0.22 から、パラレルテーブルインポートユーティリティは、LOAD DATA ステートメントと同じ方法で、入力前処理のためにデータファイルからカラムを取得できます。 選択したデータを破棄するか、データを変換してターゲットテーブルのカラムに割り当てることができます。

Oracle Cloud Infrastructure Object Storage インポート

MySQL Shell 8.0.20 までは、クライアントホストからローカルディスクとしてアクセス可能な場所からデータをインポートする必要があります。 MySQL Shell 8.0.21 から、osBucketName オプションで指定された Oracle Cloud Infrastructure Object Storage バケットからデータをインポートすることもできます。

複数のデータファイルのインポート

MySQL Shell 8.0.22 まで、パラレルテーブルインポートユーティリティでは、単一の入力データファイルを単一のリレーショナルテーブルにインポートできます。 MySQL Shell 8.0.23 からは、このユーティリティは指定されたファイルのリストをインポートすることもでき、ワイルドカードパターンマッチングをサポートしてすべての関連ファイルを場所から含めます。 ユーティリティの単一の実行によってアップロードされた複数のファイルは、単一のリレーショナルテーブルに配置されるため、たとえば、複数のホストからエクスポートされたデータを、分析に使用する単一のテーブルにマージできます。

圧縮ファイル処理

MySQL Shell 8.0.21 までは、パラレルテーブルインポートユーティリティは、圧縮されていない入力データファイルのみを受け入れます。 ユーティリティは、データファイルを分析してチャンクに配布し、チャンクをターゲット MySQL サーバーのリレーショナルテーブルにアップロードして、チャンクをパラレル接続間で分割します。 MySQL Shell 8.0.22 から、ユーティリティは、gzip (.gz) および zstd (.zst) 形式で圧縮されたデータファイルを受け入れて、ファイル拡張子に基づいてフォーマットを自動的に検出することもできます。 ユーティリティは、圧縮形式でストレージから圧縮ファイルをアップロードし、転送のその部分の帯域幅を節約します。 圧縮ファイルはチャンクに分散できないため、かわりにユーティリティはパラレル接続を使用して複数のファイルを解凍し、ターゲットサーバーに同時にアップロードします。 入力データファイルが 1 つしかない場合、圧縮ファイルのアップロードで使用できるのは 1 つの接続のみです。

MySQL Shell のパラレルテーブルインポートユーティリティでは、MySQL Shell テーブルエクスポートユーティリティからの出力がサポートされています。このユーティリティでは、生成されたデータファイルを出力として圧縮し、ローカルフォルダまたはオブジェクトストレージバケットにエクスポートできます。 パラレルテーブルインポートユーティリティのデフォルトの言語は、テーブルエクスポートユーティリティによって生成される出力ファイルのデフォルトです。 パラレルテーブルインポートユーティリティを使用して、他のソースからファイルをアップロードすることもできます。

MySQL Shell ダンプロードユーティリティ util.loadDump() は、MySQL Shell インスタンスダンプユーティリティ util.dumpInstance()、スキーマダンプユーティリティ util.dumpSchemas() およびテーブルダンプユーティリティ util.dumpTables() によって生成されたチャンク出力ファイルとメタデータの組合せをインポートするように設計されています。 ターゲットサーバーにアップロードする前にチャンク出力ファイルのデータを変更する場合は、パラレルテーブルインポートユーティリティをダンプロードユーティリティと組み合せて使用できます。 これを行うには、まずダンプロードユーティリティを使用して、選択したテーブルの DDL のみをロードし、ターゲットサーバーにテーブルを作成します。 次に、パラレルテーブルインポートユーティリティを使用して、テーブルの出力ファイルからデータを取得および変換し、ターゲットテーブルにインポートします。 必要に応じて、データを変更する他のテーブルに対してこのプロセスを繰り返します。 最後に、ダンプロードユーティリティを使用して、変更しない残りのテーブル (変更したテーブルを除く) の DDL およびデータをロードします。 手順の詳細は、ダンプしたデータの変更 を参照してください。

パラレルテーブルインポートユーティリティには、ターゲット MySQL サーバーへの既存の クラシック MySQL プロトコル 接続が必要です。 各スレッドは、独自のセッションを開いてデータのチャンクを MySQL サーバーに送信するか、圧縮ファイルの場合は複数のファイルを並行して送信します。 スレッド数、各チャンクで送信されるバイト数およびスレッド当たりのデータ転送の最大速度を調整して、ネットワーク上の負荷とデータ転送の速度を均衡化できます。 ユーティリティは、LOAD DATA ステートメントをサポートしていない X プロトコル 接続を介して動作することはできません。

インポートするデータファイルは、次のいずれかの場所にある必要があります:

  • クライアントホストからローカルディスクとしてアクセス可能な場所。

  • URL で指定された、HTTP または HTTPS を介してクライアントホストにアクセス可能なリモートの場所。 パターン一致は、この方法でアクセスされるファイルではサポートされていません。

  • Oracle Cloud Infrastructure Object Storage バケット ( MySQL Shell 8.0.21 から)。

データは、アクティブな MySQL セッションが接続されている MySQL サーバーの単一のリレーショナルテーブルにインポートされます。

パラレルテーブルインポートユーティリティでは、LOAD DATA LOCAL INFILE ステートメントを使用してデータをアップロードするため、ターゲットサーバーで local_infile システム変数を ON に設定する必要があります。 これを行うには、パラレルテーブルインポートユーティリティを実行する前に、SQL モードで次のステートメントを発行します:

SET GLOBAL local_infile = 1;

LOAD DATA LOCAL でセキュリティ上の既知の潜在的な問題を回避するために、MySQL サーバーがファイル転送リクエストを含むパラレルテーブルインポートユーティリティの LOAD DATA リクエストに応答すると、ユーティリティは事前に決定されたデータチャンクのみを送信し、サーバーによって試行された特定のリクエストは無視します。 詳細は、LOAD DATA LOCAL のセキュリティー上の考慮事項を参照してください。

関数

MySQL Shell API では、パラレルテーブルインポートユーティリティは util グローバルオブジェクトの関数であり、次のシグネチャを持ちます:

importTable ({file_name | file_list}, options)

file_name は、インポートするデータを含む単一ファイルの名前とパスを指定する文字列です。 または、file_list は、複数のデータファイルを指定するファイルパスの配列です。 Windows では、ファイルパスでバックスラッシュをエスケープする必要があります。または、代わりにスラッシュを使用できます。

  • ローカルディスク上のクライアントホストからアクセス可能なファイルの場合、ディレクトリパスに接頭辞として file://スキーマを付けるか、デフォルトのスキーマを使用できます。 この方法でアクセスされるファイルの場合、ファイルパスには、パターン一致のためのワイルドカード * (複数文字) および ? (単一文字) を含めることができます。

  • HTTP または HTTPS を介してクライアントホストにアクセスできるファイルの場合は、必要に応じて、URL または URL のリストを接頭辞として http://または https://スキーマを付けて http[s]://host.domain[:port]/path の形式で指定します。 この方法でアクセスされるファイルの場合、パターン一致は使用できません。 HTTP サーバーは Range リクエストヘッダーをサポートし、Content-Range レスポンスヘッダーをクライアントに返す必要があります。

  • Oracle Cloud Infrastructure Object Storage バケット内のファイルの場合は、バケット内のファイルへのパスを指定し、osBucketName オプションを使用してバケット名を指定します。

options はインポートオプションのディクショナリで、空の場合は省略できます。 オプションは、例の後にリストされています。

この関数は、void、またはエラーの場合は例外を返します。 インポートが Ctrl+C を持つユーザーによって途中で停止された場合、またはエラーが発生した場合、ユーティリティはデータの送信を停止します。 サーバーが受信したデータの処理を終了すると、その時点で各スレッドによってインポートされていたチャンク、完了率およびターゲットテーブルで更新されたレコード数を示すメッセージが返されます。

次の例では、MySQL ShellJavaScript モードの最初の例と MySQL ShellPython モードの次の例で、単一の CSV ファイル/tmp/productrange.csv のデータを mydb データベースの products テーブルにインポートし、ファイルのヘッダー行をスキップします:

mysql-js> util.importTable("/tmp/productrange.csv", {schema: "mydb", table: "products", dialect: "csv-unix", skipRows: 1, showProgress: true})
mysql-py> util.import_table("/tmp/productrange.csv", {"schema": "mydb", "table": "products", "dialect": "csv-unix", "skipRows": 1, "showProgress": True})

次の MySQL Shell Python モードの例では、CSV ファイルの言語のみを指定します。mydb は、MySQL Shell セッションのアクティブなスキーマです。 したがって、ユーティリティは、ファイル/tmp/productrange.csv 内のデータを mydb データベース内の productrange テーブルにインポートします:

mysql-py> \use mydb
mysql-py> util.import_table("/tmp/productrange.csv", {"dialect": "csv-unix"})

MySQL ShellPython モードの次の例では、個別に名前が付けられたファイル、ワイルドカードパターンマッチングを使用して指定されたファイルの範囲、圧縮されたファイルなどの複数のファイルからデータをインポートします:

mysql-py> util.import_table(
    [
        "data_a.csv",
        "data_b*",
        "data_c*",
        "data_d.tsv.zst",
        "data_e.tsv.zst",
        "data_f.tsv.gz",
        "/backup/replica3/2021_01_12/data_g.tsv",
        "/backup/replica3/2021_01_13/*.tsv",
    ],
    {"schema": "mydb", "table": "productrange"}
)

パラレルテーブルインポートユーティリティは、mysqlsh コマンドインタフェースを使用してコマンドラインから起動することもできます。 このインタフェースを使用して、次の例のようにユーティリティを起動します:

mysqlsh mysql://root:@127.0.0.1:3366 --ssl-mode=DISABLED -- util import-table /r/mytable.dump --schema=mydb --table=regions --bytes-per-chunk=10M --linesTerminatedBy=$'\r\n'

複数のデータファイルをインポートする場合、次の例に示すように、ワイルドカードパターンマッチングを使用して指定されたファイルの範囲は、引用符で囲まれていれば MySQL Shellglob パターンマッチングロジックによって展開されます。 それ以外の場合は、mysqlsh コマンドを入力したユーザーシェルのパターン一致ロジックによって展開されます。

mysqlsh mysql://root:@127.0.0.1:3366 -- util import-table data_a.csv "data_b*" data_d.tsv.zst --schema=mydb --table=productrange --osBucketName=mybucket

mysqlsh コマンドインタフェースを使用してパラレルテーブルインポートユーティリティを起動する場合、配列値は受け入れられないため、columns オプションはサポートされません。したがって、データファイルの入力行には、ターゲットテーブルのすべてのカラムに一致するフィールドが含まれている必要があります。 前述の例に示すように、ラインフィード文字は、この関数をサポートするシェル (bash, ksh, mkshzsh など) で ANSI-C 引用符を使用して渡す必要があります。 このインタフェースの詳細は、セクション5.8「API コマンドラインインタフェース」 を参照してください。

オプション

パラレルテーブルインポートユーティリティでは、次のインポートオプションを使用してデータのインポート場所とインポート方法を指定できます:

schema: "db_name"

接続された MySQL サーバー上のターゲットデータベースの名前。 このオプションを省略すると、ユーティリティは、接続 URI 文字列、\use コマンドまたは MySQL Shell オプションで指定された、現在の MySQL Shell セッションで使用されているスキーマ名を識別して使用しようとします。 スキーマ名が指定されておらず、セッションから識別できない場合は、エラーが返されます。

table: "table_name"

ターゲットリレーショナルテーブルの名前。 このオプションを省略すると、テーブル名は拡張子のないデータファイルの名前とみなされます。 ターゲットテーブルがターゲットデータベースに存在する必要があります。

columns: array of column names

ターゲットリレーショナルテーブルのカラムにマップされた順序で指定された、インポートファイルのカラム名を含む文字列の配列。 このオプションは、インポートされたデータにターゲットテーブルのすべてのカラムが含まれていない場合、またはインポートされたデータのフィールドの順序がテーブルのカラムの順序と異なる場合に使用します。 このオプションを省略した場合、入力行にはターゲットテーブルの各カラムに一致するフィールドが含まれると想定されます。

MySQL Shell 8.0.22 からは、このオプションを使用して、LOAD DATA ステートメントの場合と同じ方法で、入力前処理のためにインポートファイルからカラムを取得できます。 配列内のカラム名のかわりに整数値を使用すると、インポートファイル内のそのカラムは、@1 などのユーザー変数@int として取得されます。 選択したデータを破棄するか、decodeColumns オプションを使用してデータを変換し、ターゲットテーブルのカラムに割り当てることができます。

MySQL ShellJavaScript モードのこの例では、インポートファイルの 2 番目と 4 番目のカラムがユーザー変数@1 および@2 に割り当てられ、ターゲットテーブルのどのカラムにも割り当てる decodeColumns オプションはないため、これらは破棄されます。

mysql-js> util.importTable('file.txt', {
            table: 't1',
            columns: ['column1', 1, 'column2', 2, 'column3']
          });
decodeColumns: dictionary

columns オプションによってユーザー変数として取得されたインポートファイルカラムをターゲットテーブルのカラムに割り当て、LOAD DATA ステートメントの SET 句と同じ方法で前処理変換を指定する、キーと値のペアのディクショナリ。 このオプションは、MySQL Shell 8.0.22 から使用できます。

MySQL ShellJavaScript モードのこの例では、データファイルの最初の入力カラムがターゲットテーブルの最初のカラムとして使用されます。 columns オプションによって変数@1 に割り当てられた 2 番目の入力カラムは、ターゲットテーブルの 2 番目のカラムの値として使用される前に除算操作の対象となります。

mysql-js> util.importTable('file.txt', {
            columns: ['column1', 1],
            decodeColumns: {'column2': '@1 / 100'}
          });

MySQL ShellJavaScript モードのこの例では、データファイルの入力カラムが両方とも変数に割り当てられ、様々な方法で変換されて、ターゲットテーブルのカラムへの移入に使用されます:

mysql-js> util.importTable('file.txt', {
            table: 't1',
            columns: [1, 2],
            decodeColumns: {
              'a': '@1',
              'b': '@2',
              'sum': '@1 + @2',
              'multiple': '@1 * @2',
              'power': 'POW(@1, @2)'
            }
          });
skipRows: number

インポートファイルの先頭、または複数のインポートファイルの場合はファイルリストに含まれるすべてのファイルの先頭で、この数のデータ行をスキップします。 このオプションを使用して、アップロードからテーブルへのカラム名を含む初期ヘッダー行を省略できます。 デフォルトでは、行はスキップされません。

replaceDuplicates: [true|false]

既存の行と同じ値または一意インデックスを持つ入力行を置換する (true) かスキップする (false) か。 デフォルトは false です。

dialect: [default|csv|csv-unix|tsv|json]

指定したファイル形式に適した一連のフィールド処理および行処理オプションを使用します。 linesTerminatedBy, fieldsTerminatedBy, fieldsEnclosedBy, fieldsOptionallyEnclosed および fieldsEscapedBy オプションのいずれかまたは複数を指定して設定を変更することで、選択した言語をさらにカスタマイズするためのベースとして使用できます。 デフォルトの言語は、そのステートメントのデフォルト設定で SELECT...INTO OUTFILE ステートメントを使用して作成されたファイルにマップされます。 これは、MySQL Shell テーブルエクスポートユーティリティによって生成される出力ファイルのデフォルトです。 CSV ファイル (DOS または UNIX システムで作成)、TSV ファイルおよび JSON データに適したその他のダイアレクトを使用できます。 各言語に適用される設定は次のとおりです:

表 8.2 パラレルテーブルインポートユーティリティの言語設定

dialect

linesTerminatedBy

fieldsTerminatedBy

fieldsEnclosedBy

fieldsOptionallyEnclosed

fieldsEscapedBy

default

[LF]

[TAB]

[空]

false

\

csv

[CR][LF]

,

''

true

\

csv-unix

[LF]

,

''

false

\

tsv

[CR][LF]

[TAB]

''

true

\

json

[LF]

[LF]

[空]

false

[空]


注記
  1. ダイアレクトのキャリッジリターンおよびラインフィードの値は、オペレーティングシステムに依存しません。

  2. linesTerminatedBy, fieldsTerminatedBy, fieldsEnclosedBy, fieldsOptionallyEnclosed および fieldsEscapedBy オプションを使用する場合、コマンドインタプリタのエスケープ規則に応じて、バックスラッシュ文字 (\) をオプション値で使用する場合は二重にする必要があります。

  3. LOAD DATA ステートメントを使用した MySQL サーバーと同様に、MySQL Shell では、指定したフィールド処理および行処理オプションは検証されません。 これらのオプションを正しく選択しないと、データが誤ったフィールドに部分的にインポートされたり、正しくインポートされない場合があります。 インポートを開始する前に必ず設定を確認し、後で結果を確認してください。

linesTerminatedBy: "characters"

入力データファイルの各行を終了する 1 つ以上の文字 (または空の文字列)。 デフォルトは、指定された方言、または方言オプションが省略されている場合は改行文字 (\n) です。 このオプションは、LOAD DATA ステートメントの LINES TERMINATED BY オプションと同等です。 ユーティリティでは、空の文字列に設定されている LOAD DATA ステートメントの LINES STARTING BY オプションに相当するものは提供されないことに注意してください。

fieldsTerminatedBy: "characters"

入力データファイルの各フィールドを終了する 1 つ以上の文字 (または空の文字列)。 デフォルトは、指定された言語、または言語オプションが省略されている場合はタブ文字 (\t) です。 このオプションは、LOAD DATA ステートメントの FIELDS TERMINATED BY オプションと同等です。

fieldsEnclosedBy: "character"

入力データファイルの各フィールドを囲む単一の文字 (または空の文字列)。 デフォルトは、指定された言語に対するものであり、dialect オプションが省略されている場合は空の文字列です。 このオプションは、LOAD DATA ステートメントの FIELDS ENCLOSED BY オプションと同等です。

fieldsOptionallyEnclosed: [ true | false ]

fieldsEnclosedBy に指定された文字が入力データファイル (false) 内のすべてのフィールドを囲むか、場合によってのみフィールドを囲むか (true)。 デフォルトは、指定された言語、または dialect オプションが省略されている場合は false です。 このオプションにより、fieldsEnclosedBy オプションは LOAD DATA ステートメントの FIELDS OPTIONALLY ENCLOSED BY オプションと同等になります。

fieldsEscapedBy: "character"

入力データファイル内のエスケープシーケンスを開始する文字。 これを指定しない場合、エスケープシーケンスの解釈は行われません。 デフォルトは、指定された言語の場合と同様です。または、dialect オプションが省略されている場合はバックスラッシュ (\)) です。 このオプションは、LOAD DATA ステートメントの FIELDS ESCAPED BY オプションと同等です。

osBucketName: "string"

MySQL Shell 8.0.21 に追加されました。 入力データファイルが存在する Oracle Cloud Infrastructure Object Storage バケットの名前。 デフォルトでは、~/.oci/config にある Oracle Cloud Infrastructure CLI 構成ファイルの[DEFAULT]プロファイルを使用して、バケットへの接続が確立されます。 ociConfigFile および ociProfile オプションを使用して、接続に使用される代替プロファイルを置換できます。 CLI 構成ファイルの設定手順については、「SDK および CLI 構成ファイル」を参照してください。

osNamespace: "string"

MySQL Shell 8.0.21 に追加されました。 osBucketName によって指定されたオブジェクトストレージバケットが配置される Oracle Cloud Infrastructure ネームスペース。 オブジェクトストレージバケットのネームスペースは、Oracle Cloud Infrastructure コンソールのバケット詳細ページの「バケット情報」タブに表示されるか、Oracle Cloud Infrastructure コマンドラインインタフェースを使用して取得できます。

ociConfigFile: "string"

MySQL Shell 8.0.21 に追加されました。 デフォルトの場所の ~/.oci/config ではなく、接続に使用するプロファイルを含む Oracle Cloud Infrastructure CLI 構成ファイル。

ociProfile: "string"

MySQL Shell 8.0.21 に追加されました。 接続に使用される Oracle Cloud Infrastructure CLI 構成ファイル内の[DEFAULT]プロファイルではなく、接続に使用する Oracle Cloud Infrastructure プロファイルのプロファイル名。

characterSet: "charset"

MySQL Shell 8.0.21 に追加されました。 このオプションでは、インポート時に入力データが解釈される文字セットエンコーディングを指定します。 このオプションを binary に設定すると、インポート中に変換は行われません。 このオプションを省略すると、インポートでは、character_set_database システム変数で指定された文字セットを使用して入力データが解釈されます。

bytesPerChunk: "size"

複数の入力データファイルのリストの場合、このオプションは使用できません。 単一の入力データファイルの場合、このオプションでは、スレッドがターゲットサーバーへの LOAD DATA コールごとに送信するバイト数 (および行の終わりに到達するために必要な追加バイト数) を指定します。 このユーティリティは、スレッドがターゲットサーバーに取得して送信するために、データをこのサイズのチャンクに分散します。 チャンクサイズは、バイト数で指定するか、接尾辞 k (キロバイト)、M (メガバイト)、G (ギガバイト) を使用して指定できます。 たとえば、bytesPerChunk="2k"では、スレッドは約 2 キロバイトのチャンクを送信します。 最小チャンクサイズは 131072 バイトで、デフォルトのチャンクサイズは 50M です。

threads: number

入力ファイルのデータをターゲットサーバーに送信するために使用するパラレルスレッドの最大数。 スレッド数を指定しない場合、デフォルトの最大値は 8 です。 複数の入力データファイルのリストについては、指定した数または最大数のスレッドが作成されます。 単一の入力データファイルの場合、ユーティリティは次の式を使用して、この最大数までの適切なスレッド数を計算します:

min{max{1, threads}, chunks}}

ここで、threads はスレッドの最大数、chunks はデータが分割されるチャンクの数で、ファイルサイズを bytesPerChunk サイズで除算してから 1 を加算して計算されます。 この計算により、スレッドの最大数が実際に送信されるチャンクの数を超えた場合、ユーティリティは必要以上のスレッドを作成しません。

圧縮されたファイルはチャンクに配布できないため、ユーティリティはそのかわりにパラレル接続を使用して複数のファイルを一度にアップロードします。 入力データファイルが 1 つしかない場合、圧縮ファイルのアップロードで使用できるのは 1 つの接続のみです。

maxRate: "rate"

データスループットの最大制限 (バイト/秒/スレッド)。 クライアントホストまたはターゲットサーバーのネットワーク、I/O または CPU の飽和を回避する必要がある場合は、このオプションを使用します。 最大速度はバイト数で指定することも、接尾辞 k (キロバイト)、M (メガバイト)、G (ギガバイト) を使用して指定することもできます。 たとえば、maxRate="5M"では、各スレッドが 5MB のデータ/秒に制限され、8 つのスレッドで 40MB/秒の転送速度が得られます。 デフォルトは 0 で、これは制限がないことを意味します。

showProgress: [ true | false ]

インポートの進行状況情報を表示 (true) または非表示 (false) します。 デフォルトは、stdout が端末 (tty) の場合は true、それ以外の場合は false です。