MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

MySQL Shellのユーティリティをコマンドラインで実行する

はじめに

インフラエンジニアの長田です。今回は、MySQL Shellで提供されている種々の便利な機能をコマンドラインで実行する方法について紹介したいと思います。

MySQL Shellとは

MySQL Shellは、公式に提供されている新しいMySQLのコマンドラインクライアントで、従来の mysql クライアントと同様にSQLによるデータベースの操作に加え、JavaScriptまたはPythonによる操作を行うためのMySQL Shell APIを備えています。 その中の一つである util グローバルオブジェクトには、これまでのバージョンアップにより、並列スレッドで実行する高速なダンプ・リストア、テーブルデータのインポート・エクスポートなどといった便利な機能が追加されています。

MySQL ShellはWindows、Linux、macOS向けに提供されています。 dev.mysql.com

インスタンス、スキーマ、テーブルのダンプ

MySQL Shellのバージョン8.0.21より、MySQL Shellにインスタンス、スキーマ、テーブルのダンプ・リストアユーティリティが追加されました。この機能は並列スレッド(デフォルト4、変更可能)で実行することにより、シングルスレッドで実行する従来のmysqldumpと比較して高速な論理バックアップ、およびリストアを行うことができます。また、テーブルのレコードにあたるファイルは自動的にzstdで圧縮されるため、リダイレクトして圧縮コマンドを使うことなくストレージ領域の節約が可能です。この機能はMySQL5.6以降のMySQLインスタンスに対して使用することができます。

インスタンスのダンプを出力する場合、通常は mysqlsh コマンドを使用してデータベースに接続し、MySQL Shellのプロンプト上で util グローバルオブジェクトの関数 dumpInstance() を実行します。 例として、some_host というホストに dump_user というユーザで接続し、データベース全体のダンプを /path/to/dir というディレクトリに出力する場合、以下のようになります。

$ mysqlsh -h some_host -u dump_user -p

 MySQL  some_host:3306  JS > util.dumpInstance("/path/to/dir")

実行するユーザに最低限必要な権限は、EVENT , SELECT , SHOW VIEW , TRIGGER です。加えて、一貫性のあるバックアップを取得するために BACKUP_ADMIN (MySQL8.0以降のみ、5.7以前では不要)と、 RELOAD または LOCK TABLES が必要です。また、バイナリログ位置などのレプリケーション情報を取得する場合、 REPLICATION CLIENT 権限が必要です。その他、扱うデータとバージョンにより追加の権限が必要になりますので、詳しくは上記リンクの公式リファレンスをご参照ください(日本語版には未翻訳の内容があるため、英語版もあわせてご確認ください)。

この機能は、"--"オプションを使用することで、API コマンドラインインタフェースによるコマンドライン実行ができます。 上記と同じ内容をコマンドライン実行する場合、以下のように -- util dump-instance というオプションを付与し、引数として出力先ディレクトリを指定します ( --util の間に半角スペースを挟む必要がある点に注意が必要です)。

$ mysqlsh dump_user:<password>@some_host -- util dump-instance /path/to/dir

MySQL Shellにはパスワードの保存機能があるため、あらかじめ使用するユーザでログインしておくことにより、コマンド実行時にパスワードの入力を省略することができます。

同様に、スキーマ単位でのダンプ出力は -- util dump-schemas 、 テーブル単位でのダンプ出力は -- util dump-tables で実行できます。

これらのダンプコマンドには、並列スレッド数や転送量の制限、除外するスキーマ・テーブルの設定といった豊富なオプションが用意されています。 詳細は mysqlsh -- util dump-instance --help コマンド等でご確認ください。

ダンプのロード

ダンプしたデータのロードは、 util グローバルオブジェクトの関数 loadDump() によって実行します。 これも同様に、コマンドラインで実行する場合は -- util load-dump というオプションを付与し、引数としてダンプファイルのあるディレクトリを指定します。

$ mysqlsh root@localhost -- util load-dump /path/to/dir

この機能によりリストアを行う場合、 local_infile システム変数をONにする必要があります。MySQL8.0以降はデフォルトでOFFとなっているため、 /etc/my.cnflocal_infile=1 を追記してMySQLを起動するか、起動中のMySQLに接続して SET GLOBAL local_infile=1 を実行する必要があります(MySQL8.0以降の場合は、 SET PERSIST local_infile=1 を実行することで再起動後も設定が維持されます)。

従来のリストアコマンドにない利点として、 --includeSchemas または --includeTables オプションにより、ダンプファイルから特定のスキーマ・テーブルのみをリストアすることができます。 以下のようにリストアするテーブルを schema.table としてカンマ区切りで列記して使用します。

$ mysqlsh root@localhost -- util load-dump /path/to/dir --includeTables=foo_db.table_a,bar_db.table_b

テーブルデータのインポート・エクスポート

従来の LOAD DATA LOCAL INFILE ステートメントのような、ファイルをテーブルにインポートするには util グローバルオブジェクトの関数 importTable() によって実行します。この関数も並列スレッドで実行することができ、またgzipやzstdにより圧縮しているファイルでもインポートすることが可能です。 コマンドラインで実行する場合は -- util import-table というオプションを付与します。 --table オプションでインポートするテーブルを指定し、 --dialect オプションでファイル形式を指定します。実行時に使用するユーザには INSERT および FILE 権限が必要です。また、ダンプのロードと同様に local_infile システム変数をONにする必要があります。

$ mysqlsh import_user@localhost/test_db -- util import-table /var/lib/mysql-files/test_import_data.csv.zst --table=test_table --dialect=csv-unix

テーブルデータのエクスポートは、 util グローバルオブジェクトの関数 exportTable() によって実行します。コマンドラインで実行する場合は -- util export-table というオプションを付与します。エクスポートの際も、 --compression オプションによりファイルを圧縮して出力することができます。実行するユーザには SELECT 権限が必要です。

$ mysqlsh export_user@localhost/test_db -- util export-table test_table /tmp/test_export_data.csv.zst --dialect=csv-unix --compression=zstd

おわりに

コマンドラインによるユーティリティの実行により、スクリプトファイルやcronジョブ、各種バッチジョブ管理ツールといったより便利な形での活用が可能となります。 活用例としては、 util.dumpInstance() をスケジュール実行することによる定期的なバックアップ取得が考えられます。並列スレッドによる高速な実行や、特定のテーブルのみダンプロードする機能などのメリットがあるため、mysqldumpやXtrabackupに代わるバックアップの選択肢ともなり得そうです。

以上の内容がMySQLをご利用されている方の参考になれば幸いです。最後まで読んで頂きありがとうございました。