以前の記事で、マルチスレッド処理を使用して MySQL Shell でデータをダンプおよびロードする方法について説明しました。util.dumpInstance() を使用すると、以前にダンプされたものも含めて、すべてのデータとスキーマの変更をダンプします。しかし、最後のダンプ以降に発生したデータとスキーマの変更だけをダンプしたい場合はどうすればよいでしょうか?この記事では、MySQL Shell と util.dumpBinlogs() を使用してこれを実現する方法を紹介します。

セットアップ

このデモでは、ポート 2319 と 2320 で実行されている 2 つの MySQL サンドボックス を作成しました。ポート 2319 で実行されているインスタンスで以下のコマンドを実行し、新しいスキーマとテーブルを作成して、テーブルにデータを追加しました。


create schema demo;

create table demo.progress
(
    id    int auto_increment
        primary key,
    name  varchar(50) not null,
    score int         not null
);

insert into demo.progress(name, score)
values('Sullivan', 99479),
      ('Randall', 99351),
      ('Sanderson', 58986);

ご覧の通り、これは 3 つのカラムだけを持つシンプルなテーブルです。

これらのスクリプトの実行後、util.dumpInstance('~/dumps/binlog_setup') を実行して、ダンプをホームフォルダの下の dumps/binlog_setup ディレクトリに保存しました。

次に、ポート 2320 のサンドボックスインスタンスに切り替え、util.loadDump('~/dumps/binlog_setup') を実行してダンプをこのサンドボックスにロードしました。

これで両方のインスタンスは同期されています。

大規模なデータセットや複雑なスキーマを持つ MySQL システムでは、このように全体を移す形だと、あるインスタンスから別のインスタンスにデータを移動するのに時間がかかることがあります。

データとスキーマの変更を追加する

ポート 2319 で実行されているインスタンスにいくつかのデータとスキーマの変更を加えてみましょう。


insert into demo.progress(name, score)
values('Lucky', 68245),
      ('Peterson', 67236);

create schema demo2;

バイナリログのダンプ

データとスキーマを変更したので、util.dumpBinlogs() を使用してバイナリログをダンプできます。以下はその構文です。

util.dumpBinlogs('~/dumps/binlog_dump', {since:'~/dumps/binlog_setup'})

このコマンドは、MySQL Shell にバイナリログをホームフォルダ下の dumps/binlog_dump ディレクトリにダンプするよう指示します。since オプションは、最後のダンプ以降に発生したバイナリログのみをダンプするよう MySQL Shell に伝えます。この場合、最後のダンプは dumps/binlog_setup ディレクトリに保存されています。この場所は、ひとつ前の手順で util.dumpInstance('~/dumps/binlog_setup') を実行したときに作成されたダンプです。since の値は、util.dumpInstance() または util.dumpBinlogs() の以前の呼び出しの結果を指定できます。

バイナリログのロード

増分の変更をダンプしたので、ポート 2320 で実行されているインスタンスにバイナリログをロードできます。以下がその構文です。

util.loadBinlogs('~/dumps/binlog_dump', {ignoreGtidGap:true})

このコマンドは、MySQL Shell にホームフォルダ下の dumps/binlog_dump ディレクトリからバイナリログをロードするよう指示します。ignoreGtidGap オプションは、ソースインスタンスとターゲットインスタンスの間の GTID ギャップを無視するように、MySQL Shell に指示します。今回のサンプル実行時に GTID シーケンスのギャップについてのエラーが発生した理由は追う時間がなかったためよくわかりませんでした(別の日に調査結果を記事にするかもしれません)が、このオプションを使用することでその問題を回避することができました。

変更の確認

バイナリログをロードしたので、ターゲットインスタンスにデータとスキーマの変更が正しく適用されたことを確認できます。まず、以下のコマンドを実行して確認しましょう。

show schemas;

結果は以下のようになるはずです。

+--------------------+
| Database           |
+--------------------+
| demo               |
| demo2              |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

demo2 がスキーマとして移行に成功し、一覧表示されていることに注目してください。

続いて、次のコマンドでデータの変更が正しく適用されたかを確認します。

select * from demo.progress;

LuckyとPetersonのレコードがテーブルに正常に追加されたことが、クエリの結果から読み取れます。

+----+-----------+-------+
| id | name      | score |
+----+-----------+-------+
|  1 | Sullivan  | 99479 |
|  2 | Randall   | 99351 |
|  3 | Sanderson | 58986 |
|  4 | Luckey    | 68245 |
|  5 | Peterson  | 67236 |
+----+-----------+-------+

まとめ

MySQL Shell は、データを迅速にダンプおよびロードできる強力なツールです。以前紹介した util.dumpInstance() util.loadInstance() は、以前にダンプされたことがあるかどうかにかかわらず、すべてのデータとスキーマの変更をダンプおよびロードします。対照的に、util.dumpBinlogs() と util.loadBinlogs() を使えば、データの増分分だけをダンプできます。このアプローチは、特に大規模なデータセットや複雑なデータベーススキーマの管理に役立ち、変更をより効率的かつオーバーヘッドの少ない方法で適用できます。

(訳者註: 本記事の翻訳前の元記事は、2025 年 3 月 27 日に公開されました)