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

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

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

mysqldiskusage データベースのディスク仕様量の表示

接続先を指定すれば、その接続先のデータベースディスク利用量を計算してくれます。以下が実行例です。

mysqluc> mysqldiskusage --server=root:root@localhost:3306
  # Source on localhost: ... connected.
  # Database totals:
  +---------------------+-------------+
  | db_name             |      total  |
  +---------------------+-------------+
  | mydb                | 406,979     |
  | mysql               | 1,645,921   |
  | performance_schema  | 510,023     |
  | sakila              | 30,495,478  |
  | test                | 123,270     |
  | world               | 471,349     |
  +---------------------+-------------+
Total database disk usage = 33,653,020 bytes or 32.09 MB
#...done.

各種ログ類のサイズも結果に含めることができます。バイナリログ(-b), リレーログ(-r), 一般ログ・スロークエリ・エラーログ(-l), InnoDB関連(InnoDBログ、共有テーブルスペース)ファイル(-i)を個別に指定するか、-aですべてを表示するようにしてください。

ただし、図2のようにユーティリティをローカルで実行する場合とリモートで実行する場合には、取得できる情報に差があります。

図2:ローカルとリモートの差(クリックで拡大)

mysqlindexcheck 重複、もしくは冗長なインデックスをチェック

データベースのパフォーマンスアップにはインデックスの設計、追加が不可欠です。しかしながら大規模でテーブル数・カラム数が多い場合や、長期にわたって多人数によるメンテナンスが実施されたテーブルなどでは、重複したインデックスや、冗長なインデックスが作成されていることがよくあります。

本ユーティリティはそのチェックに利用できます。チェック内容は表とインデックスの定義から静的にチェックされ、あくまでもサジェスチョンであることにお気をつけください(すべてが正しいとは限りませんので、すべてに対処が必要とは限りません)。

例えば以下のような定義があるとき、idx2があればidx1は不要です。

create table t1(i1 int, v2 varchar(20)) engine=myisam;
  insert into t1 values(1,'Firebird'),(2,'MySQL'),(3,'PostgreSQL');
  create index idx1 on t1(i1);
  create index idx2 on t1(i1,v2);

このテーブルのインデックスチェックを、修正のためのDROP文も表示(-d)するオプション込みで行うと以下の実行例となります。

mysqluc> mysqlindexcheck --server=root:root@localhost:3306 -d test.t1
  # Source on localhost: ... connected.
  # The following index is a duplicate or redundant for table test.t1:
  #
  CREATE INDEX `idx1` ON `test`.`t1` (`i1`) USING BTREE
  #     may be redundant or duplicate of:
  CREATE INDEX `idx2` ON `test`.`t1` (`i1`, `v2`) USING BTREE
  #
  # DROP statement:
  #
  ALTER TABLE `test`.`t1` DROP INDEX `idx1`;
  #

結果としてidx1が冗長、もしくは重複としてカウントされ、DROP文が表示されます。

MySQLのインデックスについて詳細は米facebookの松信さんがサン・マイクロシステムズ勤務時代に作成した次のドキュメントが役立ちます。ご興味のあるかたはご参照ください。

> インデックスを使いこなす

また参考文献にあげた拙書や奥野さんの本にもインデックスの説明と、その効果を確認するためのEXPLAIN句の読み方の情報があります。

mysqlmetagrep メタデータの検索

データベースオブジェクト('database', 'trigger', 'user','routine', 'column', 'table', 'partition', 'event', 'view')から指定パターンのオブジェクトを検索します。grepと名前がついていますが、デフォルトの検索はLIKEにより行われます。

例えばTで始まるデータベースから、Tで始まるテーブル、ビューを検索するには以下の実行例で検索します。

mysqluc> mysqlmetagrep --server=root:root@localhost:3306 -e 't%' --search-objects=table,view --database='t%' --format=vertical
  *************************       1. row *************************
  Connection: root:*@localhost:3306
  Object Type: TABLE
  Object Name: t1
  Database: test
  Field Type: TABLE
  Matches: t1
  1 row.

検索対象のデータベースオブジェクト種別は上記のように--search-objectsオプションにカンマで区切って指定できます。
--search-objectsを指定しない場合は、すべてのデータベースオブジェクトがリストアップされ大変なことになります。

またストアドルーチン、トリガ、イベントのBODY部分も検索対象にしたい場合には-bオプションもあわせて指定してください。

mysqlprocgrep プロセス情報の検索

MySQLではクライアントからの各接続の状態をSHOW FULL PROCESSLIST;(もしくは、同内容をSQLにて絞り込める情報スキーマ(I_S)のPROCESSLISTテーブル)にて確認できますが、mysqlprocgrepはI_Sと同等の絞り込みに加えてアクション(クエリのKILL, 接続のKILL)を行えるようにしたものです。

例えば現在の処理を4時間(14400秒)より長く続けている接続の一覧を取得する場合、I_Sの場合は以下のクエリにて求めます。

mysql> select * from information_schema.processlist where time > 14400;

同じ処理をmysqlprocgrepで行うには以下の実行例にて検索します。

mysqluc> mysqlprocgrep --server=root:root@localhost:3306 --age=4:00:00
  +------------------------+-----+-------+------------------+-------+----------+--------+--------+-------+
  | Connection             | Id  | User  | Host             | Db    | Command  | Time   | State  | Info  |
  +------------------------+-----+-------+------------------+-------+----------+--------+--------+-------+
  | root:*@localhost:3306  | 13  | root  | localhost:53549  | None  | Sleep    | 27634  |        | None  |
  | root:*@localhost:3306  | 36  | root  | localhost:57658  | test  | Sleep    | 17770  |        | None  |
  +------------------------+-----+-------+------------------+-------+----------+--------+--------+-------+

Commandで絞り込むには--match-commandオプション、Stateで絞り込むには--match-stateオプションで絞り込めます。またそのほかの項目(id,user,host,db,info)でも同様の書式(--match-項目)で絞り込めます。
絞り込んだ結果、当該クエリのKILLには--kill-queryオプション、当該接続のKILLには--kill-connectionオプションを指定します。

例えば、CommandがSleepになって4時間(14400秒)より長い時間経っている接続をKILLするには、以下のオプションにて実行します。

mysqluc> mysqlprocgrep --server=root:root@localhost:3306 --age=4:00:00 --match-command='Sleep' --kill-connection
著者
木村 明治(きむらめいじ)
日本オラクル株式会社
日本オラクル株式会社MySQLサポートエンジニア。
MySQL以外にもFirebirdをはじめとするオープンソースデータベースの世界で活動している。
著書に「Firebird徹底入門」(共著)、「プロになるためのデータベース技術入門〜MySQL For Windows〜」

連載バックナンバー

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

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

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

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