情シスは何度でも甦るさ。

OracleDB/Ruby好きの情シス部員がお送りします

zabbixのデータが増えすぎ問題

去年、監視のために導入したzabbix(ver2.4)ですが、対象サーバが、120台くらいあり、テンプレートの監視項目をそのまんま適用してたら、高負荷状態になり、画面ももっさり、監視ももっさりしてきてしまった。

導入後に、zabbixサーバ自体のメンテを怠ってたのは知っていて、いつか対応しなきゃね。って話を、導入した協力会社の人としてたんだが、その人がいなくなってしまい、対応できるのが他におらず、対応することに。

STEP1. 監視項目の見直し

まず、アイテム(監視項目)の減少。 テンプレートの監視項目をすべて適用しているので、一旦、最低限必要なものを覗いて、監視項目を無効化してまわる。
最低限必要なものとは、PING監視と、ディスク容量監視と、アプリケーションログの監視。

3600ほどあった有効な監視項目を1600ほどに削減。(有効になってても実際に監視に使ってない項目もある)

STEP2. データ容量の見直し

過去データを削除するが、対象テーブルの特定。

サイズを調べてみる。(こちらの記事を参考:データベースとテーブルのサイズを確認する方法 - ふってもハレても

table_name engine tbl_rows rlen allMB dMB iMB
history_uint InnoDB 136449572 74 14039 9748 4291
history InnoDB 17177763 69 1734 1131 603
trends_uint InnoDB 14692072 80 1134 1134 0
events InnoDB 3087769 72 444 212 232
history_log InnoDB 700203 202 173 135 38
trends InnoDB 2045698 74 146 146 0

hisutory_uintの1.3億レコードにびびるが、色々、サイトを見て回ると、データを圧縮しつつ、データファイルをテーブルごとに分割すると良いよとのこと。 mysqlのバージョン的にも適合するので、これでいくことに。

httpd、zabbix-server、mysqldのサービスを止めて、my.cnfを書き換える。

/etc/my.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

character-set-server=utf8

#ここから追加
ignore-builtin-innodb
plugin-load=innodb=ha_innodb_plugin.so;innodb_trx=ha_innodb_plugin.so;innodb_locks=ha_innodb_plugin.so;innodb_lock_waits=ha_innodb_plugin.so;innodb_cmp=ha_innodb_plugin.so;innodb_cmp_reset=ha_innodb_plugin.so;innodb_cmpmem=ha_innodb_plugin.so;innodb_cmpmem_reset=ha_innodb_plugin.so
innodb_file_per_table
innodb_file_format=Barracuda
#ここまで

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

mysql起動し、alter tableで対象のテーブルを再構成していく。
history_uintは、でかいので後回しに。

alter table

alter table history ENGINE=INNODB ROW_FORMAT=Compressed;
alter table trends ENGINE=INNODB ROW_FORMAT=Compressed;
alter table trends_uint ENGINE=INNODB ROW_FORMAT=Compressed;
alter table history_log ENGINE=INNODB ROW_FORMAT=Compressed;
alter table events ENGINE=INNODB ROW_FORMAT=Compressed;

再度、データサイズをチェック

table_name engine tbl_rows rlen allMB dMB iMB
history_uint InnoDB 156635215 65 14047 9751 4296
history InnoDB 16962930 33 774 534 239
trends_uint InnoDB 15694129 34 523 523 0
events InnoDB 3073469 31 204 92 111
history_log InnoDB 746147 94 86 67 18
trends InnoDB 1963177 37 69 69 0

データファイルが別ファイルになっているか確認

ls -lh /var/lib/mysql/zabbix/*.ibd
-rw-rw---- 1 mysql mysql 212M  7月 24 15:21 2017 /var/lib/mysql/zabbix/events.ibd
-rw-rw---- 1 mysql mysql 792M  7月 24 15:21 2017 /var/lib/mysql/zabbix/history.ibd
-rw-rw---- 1 mysql mysql  92M  7月 24 15:21 2017 /var/lib/mysql/zabbix/history_log.ibd
-rw-rw---- 1 mysql mysql  64K  7月 24 15:57 2017 /var/lib/mysql/zabbix/history_uint_new.ibd
-rw-rw---- 1 mysql mysql  76M  7月 24 15:21 2017 /var/lib/mysql/zabbix/trends.ibd
-rw-rw---- 1 mysql mysql 536M  7月 24 15:21 2017 /var/lib/mysql/zabbix/trends_uint.ibd

大体サイズは半分になってる。 しかし、最大のテーブル、history_uintがやっかい。なにせ1.5億レコード。

えい、ままよやってまえ!

alter table history_uint ENGINE=INNODB ROW_FORMAT=Compressed;

週末流しっぱにしてたが、60時間たってもSQL終わらず。。。 あえなくKILL。こりゃtruncateしちゃうか。と考えるが、英語のサイトで、別テーブル作成して、任意の期間のデータをコピーして、リネームする手順が紹介されてた。

CLEANING UP THE ZABBIX DATABASE

CREATE TABLE history_uint_new LIKE history_uint;
INSERT INTO history_uint_new SELECT * FROM history_uint WHERE clock > '[timestamp]';

20日間ほどのデータを退避しようとしたが、そもそもSELECTが終わらねえ。うーん。 なので、空のテーブルのまま、TABLEを切り替えることに。(意味なし)

table 切り替え。再度、zabbixを起動して、問題なければDrop table実行

ALTER TABLE history_uint RENAME history_uint_old;
ALTER TABLE history_uint_new RENAME history_uint;    
DROP TABLE history_uint_old;

で、3週間くらいたった。

table_name engine tbl_rows rlen allMB dMB iMB
history_uint InnoDB 37300965 28 1496 997 499
trends_uint InnoDB 14785949 36 509 509 0
history InnoDB 7749555 40 423 299 124
events InnoDB 2530589 31 172 76 95
trends InnoDB 1704568 36 59 59 0
history_log InnoDB 339517 102 43 33 10

サイズは、対応前の15%程度。 大丈夫そうなので、必要なサーバに関しては、リソース系の監視項目を追加しようと考え中。