Re:dashとMySQLとPerlで泥臭くMySQLテーブルの容量(概算値)を時系列でモニタリング

ぬいぐるみが好きな方のDBAです。
このエントリーは Tableau Serverで簡単にMySQLテーブルの容量(概算値)を時系列でモニタリング に対する8か月ぶりの当てつけエントリーです。はふん。
前提として、上記のTableau Serverでテーブル容量をモニターしているやつは、RDSのようですが、DBチームが戦うMySQLサーバーはデータセンターに設置されています。物理だったり仮想だったり、バージョンも上は5.7から下は4.0(そう、かつて 三日間戦争 を繰り広げたあのサーバーです、はふん)まで、information_schemaなんて存在しないMySQLもいっぱいあります。あと、くだんの環境はAWSで動いているようでナウいTableau Serverとかあるようですが、データセンター側にはそんなものはありませんので、自分たちで何とかしないといけません。
というわけで、データセンター組の泥臭いMySQLのテーブル容量監視です。構成要素はこんな感じ。
SHOW TABLE STATUS
を取りに行くPerlのスクリプト- Perlから受け取ったデータを保管するためのMySQL
- Dockerの上に乗っかった Re:dash
Re:dashなのは趣味です。正直MySQL WorkbenchからCSVかTSVに吐かせてExcelでもいいと思う。というかMySQL Workbenchにグラフ描画機能があれば最強なんじゃないか。Dockerの上に乗っけているのは既存の環境を汚さずに好きなところに置けるからですね。
スクリプトはこんな感じです。
sub show_table_status
{
my ($self, $schema)= @_;
my @ret; debugf("Dumping table status from %s", $schema);
return 0 if grep {/^$schema$/} (IGNORE_SYSTEM_SCHEMA);
foreach my $table (@{$self->{conn}->selectall_arrayref("SHOW TABLE STATUS FROM `$schema`", {Slice => {}})})
{
push(@ret, {schema => $schema,
table => $table->{Name},
rows => $table->{Rows},
data_size => $table->{Data_length},
index_size => $table->{Index_length},
free_size => $table->{Data_free},
engine => $table->{Engine} ? $table->{Engine} : $table->{Type} ? $table->{Type} : ""});
}
return 0 unless scalar(@ret);
return \@ret;
}
MySQL側で保管しておくのはこんな感じ。
mysql> SHOW CREATE TABLE table_status_info\G
*************************** 1. row ***************************
Table: table_status_info
Create Table: CREATE TABLE `table_status_info` (
`seq` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`ipaddr` varchar(15) NOT NULL,
`port` smallint(5) unsigned NOT NULL,
`table_schema` varchar(255) NOT NULL,
`table_name` varchar(255) NOT NULL,
`rows` bigint(20) unsigned NOT NULL,
`data_size` bigint(20) unsigned NOT NULL,
`index_size` bigint(20) unsigned NOT NULL,
`free_size` bigint(20) unsigned NOT NULL,
`engine` varchar(32) NOT NULL,
`registered` datetime NOT NULL,
PRIMARY KEY (`seq`),
KEY `idx_ipaddr_port_name` (`ipaddr`,`port`,`table_name`),
KEY `idx_ipaddr_port_schema_name` (`ipaddr`,`port`,`table_schema`,`table_name`),
CONSTRAINT `table_status_info_ibfk_1` FOREIGN KEY (`ipaddr`, `port`) REFERENCES `instance_info` (`ipaddr`, `port`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=34432729 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
至極自然な感じですね。
あとはRe:dashを浮かせたホストからこのテーブルへのSELECT権限をつけて、Re:dashのデータソースにデータ保管用のMySQLを作ると

こんな感じ。テーブル容量の他にも SHOW GLOBAL STATUS
とか SHOW GLOBAL VARIABLES
とか SHOW GRANTS
とか色々見られます。 sys.statement_analysis のサマリーも食わせるようにしようかと計画中。
Have Fun!!