Pythonで作られた便利なコマンドラインツール MySQL Utilities

2014年2月11日(火)
木村 明治(きむらめいじ)

データベース管理に便利なユーティリティ(対象のサーバーが複数)

--server=SERVER相当のオプションを二つ以上指定することにより、複数のサーバー(インスタンス)を対象として処理を行うことができるユーティリティを紹介します。

図3はmysqlservercloneで作成した新規のインスタンスと、そのオリジナルとなった既存のインスタンスの両方に、それぞれポート番号3307, 3306でアクセスするイメージ図です。

図3:2つのインスタンス(クリックで拡大)

mysqlserverclone 動作中のMySQLを元に別インスタンスを開始

現在すでに動作しているMySQLサーバーの複製を、同じサーバー上に作りたい場合にはmysqlservercloneが利用できます。

これは稼働しているMySQLに接続して同じバイナリを用いて違うインスタンス(datadir, port, socket等が違う)を生成します。コマンドの名称はクローン(clone)となっていますが、その名称の印象からうける以下のような処理は行われません。

  • クローン元からデータベースオブジェクト(表、ビュー、プロシジャ、トランザクション、等)は引き継がない。あくまで新規のMySQLインスタンスとなる。
  • my.cnfは引き継がない。デフォルトでは--no-defaults指定となり、mysqlclonecommandのオプションで暗黙的に指定されたもの(--new-dataで指定されたものが--datadirになる)や、明示的に指定されたもの(--mysqld=明示的なオプション)が指定される。

まずは以下のコマンドで新しいMySQLサーバーのインスタンスを作製してみましょう。

mysqluc> mysqlserverclone --server=root:root@localhost:3306 --new-data=c:/users/meiji/data2 --root-password=root -w c:/users/meiji/start.txt
  # Cloning the MySQL server running on localhost.
  # Creating new data directory...
  # Configuring new instance...
  # Locating mysql tools...
  # Setting up empty database and mysql tables...
  # Starting new instance of the server...
  # Testing connection to new instance...
  # Success!
  # Setting the root password...
  # Connection Information:
  #  -uroot -proot --port=3307
  #...done.

他のコマンドプロンプトから以下のコマンドラインで新しいインスタンスに接続できます。

mysql -uroot -proot --port=3307

また --server2=root:root@localhost:3307 とすると、MySQL Utilitiesの2つ目のサーバーとして指定できます。

mysqldbcopy サーバー間でのデータベースのコピー

mysqlindexcheckの際に作ったテーブル含むtestデータベースを同じ名称で、新しいインスタンスにコピーしてみましょう。以下のコマンドでコピーできます。

mysqluc> mysqldbcopy --source=root:root@localhost:3306 --destination=root:root@localhost:3307 test
  # Source on localhost: ... connected.
  # Destination on localhost: ... connected.
  # Copying database test
  # Copying TABLE test.t1
  # Copying GRANTS from test
  # Copying data for TABLE test.t1
  #...done.

コピー元に対するロックは--locking=snapshotがデフォルトとなっています(mysqldumpの--single-transactionと同じ)。すべてをロックするには--locking=lock-all、ロックを取得しない場合には--locking=no-locksを指定してください。

直接2つのインスタンスに接続できない場合には、mysqldbexportとmysqldbimportの組み合わせ利用をご検討ください。

mysqldiff データベースオブジェクト定義の比較

mysqldiffはデータベースオブジェクトの定義比較を行います。先ほどコピーした内容を比較してみましょう。

mysqluc> mysqldiff --server1=root:root@localhost:3306 --server2=root:root@localhost:3307 test:test
  # server1 on localhost: ... connected.
  # server2 on localhost: ... connected.
  # Comparing `test` to `test`                                       [PASS]
  # Comparing `test`.`t1` to `test`.`t1`                             [PASS]
  Success. All objects are the same.

今回では定義は同一でしたが、差分が出た時、デフォルトではserver1を基準として差分が表示されます。

server2を基準とする場合には--cahnges-for=server2を指定してください。また差分取得に失敗すると処理は途中で打ち切られます。最後まで実行するには--foreceオプションを指定して実行してください。

mysqldbcompare データベース比較

表の場合mysqldiffは表の定義だけを比較しますが、mysqldbcompareは定義以外にも件数や内容も確認します。その確認のため、主キーを各テーブルに設定してください。主キーが設定されていない場合には、比較の一部がスキップされ、結果として比較が失敗します。

以下は主キーがないためデータのチェック(Data Check)がスキップされ、比較が失敗する例です。

mysqluc> mysqldbcompare --server1=root:root@localhost:3306 --server2=root:root@localhost:3307 test:test
  # server1 on localhost: ... connected.
  # server2 on localhost: ... connected.
  # Checking databases test on server1 and test on server2
  #
  #                                                   Defn    Row     Data
  # Type      Object Name                             Diff    Count   Check
  # -------------------------------------------------------------------------
  # TABLE     t1                                      pass    pass    SKIP
  #
  # No primary key found.

  # Database consistency check failed.
  #
  # ...done

server1, server2の双方にalter table t1 add primary key(i1);を実行すると、Data Checkも行われます。

件数や内容の確認には、すべてのレコードを確認する必要があるので、長大なテーブルを確認するのには、それ相応の時間がかかることにご注意ください。
mysqldbcompareは比較して不一致があるとエラー終了してしまうため、最後までチェックするには-aオプションを指定して実行すると良いでしょう。

その他のユーティリティ

mysqlrpl*のユーティリティはレプリケーション構成のMySQLサーバーに役立つツール群です。これらのツールの動作確認にはmysqlservercloneとmysqlreplicationの組み合わせでレプリケーション構成を作成して確認できますが、複雑な構成の構築には結構手間がかかります。このような場合はMySQL SandboxというPerlのツール群にて構築すると、簡単にさまざまな構成のレプリケーションが作成できます。

また監視するレプリケーションがすべてMySQL 5.6.x以降のバージョンで構成され、GTID(Global Transaction ID)が設定(gtid_mode=ON)されている場合には、Master:Slave = 1:n (nは2以上)のレプリケーション構成で監視と自動フェイルオーバーを行えるmysqlfailoverを利用することができます。利用方法は複雑であるため次のマニュアルをよくご確認のうえご利用ください。

> 5.9.1. mysqlfailover — Automatic replication health monitoring and failover

残念ながらMySQL 5.5以前のバージョンではGTIDの機能がないため、mysqlfailoverは利用できません。その場合は米facebookの松信さんがDeNA勤務時代に開発したPerlスクリプト群であるMHA(Master High Availability manager and tools) for MySQLのご利用を検討されてはいかがでしょうか?

MySQL-MHAの詳細は次のドキュメントをご参照ください。

> Announcing MySQL-MHA: "MySQL Master High Availability manager and tools"

MySQL-MHAについては参考文献にあげたRonald/Chrisの本にも説明があります。

さて次回は、Workbenchの商用版にのみ追加されている機能と、その他商用版のMySQLに付属する便利なツールについて説明したいと思います。

【参考文献】

  • 木村明治『プロになるためのデータベース技術入門 MySQL for Windows 困ったときに役立つ開発・運用ガイド』技術評論社(発行年:2012)
  • 奥野幹也『エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド』技術評論社(発行年:2010)
  • Charles Bell『Expert MySQL SECOND EDITION』Apress(発行年:2012)
  • Ronald Bradford/Chris Schneider『Effective MySQL Replication Techniques in Depth』Oracle Press(発行年:2012)
著者
木村 明治(きむらめいじ)
日本オラクル株式会社
日本オラクル株式会社MySQLサポートエンジニア。
MySQL以外にもFirebirdをはじめとするオープンソースデータベースの世界で活動している。
著書に「Firebird徹底入門」(共著)、「プロになるためのデータベース技術入門〜MySQL For Windows〜」

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています