はじめに
インフラエンジニアの長田です。今回は、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.cnf
に local_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をご利用されている方の参考になれば幸いです。最後まで読んで頂きありがとうございました。