ZABBIXサーバーの"/"パーティションがずーっと逼迫していた
うちにはRHEL6→RHEL8にバージョンアップ移行させたZABBIXサーバーがある。
設定の大半をRHEL6時代のまま移行したのだが、1年ぐらい経って妙に"/"パーティションが逼迫していることに気づいた。
ヒストリとかトレンドデータが溜まりすぎているのかな・・・と思い、データ保存期間を短縮したり、手動でhousekeeperしたり、Alter tableでDBテーブル圧縮したり、truncateコマンドでDBテーブルそのものを空にしたりしたのだが、どうにも効果が薄い。そしてデータ保存期間を超過しているにも関わらず、"/"パーティションのディスク使用量はじわりじわりと増えていっていた。
参考:当時実行していたtruncateコマンド。DBテーブルを空にして再作成する(history_uintテーブルを主に対象としていた。ID/PASS/テーブル名等変数は適当に読み替えされたし)
#systemctl stop zabbix-server
#mysql -u zabbix -p zabbix -e 'truncate table history_uint'
Enter password:
#systemctl start zabbix-server
参考:各テーブルの使用状況確認コマンド(ID/PASS/テーブル名等変数は適当に読み替えされたし)
#mysql -u zabbix -p zabbix -e 'select table_schema,table_name,table_rows,ROUND((data_length+index_length+data_free)/1024/1024/1024) as "Total GB",ROUND((data_length+index_length)/1024/1024/1024) as "Usage GB",ROUND((data_free)/1024/1024/1024) as "Free GB" from information_schema.tables where table_schema = "zabbix"';
参考:手動housekeeperの実行
#zabbix_server -R housekeeper_execute
参考:Alter tableコマンド。対象テーブルを圧縮する(新規にテーブルを作成して綺麗にデータをコピーするので、対象テーブルのサイズと同じくらいのディスク空き容量が必要なので実行するなら注意)
#mysql -u zabbix -p zabbix -D zabbix -e "alter table history_uint ENGINE=InnoDB;"
参考:テーブルサイズの確認
#cd /var/lib/mysql/zabbix
#ll *.ibd -hS|head
【原因】snmptt.degubのlogrotateが上手く行っていなかった
肥大化ファイル探しでログ周りの調査
あまりにDBテーブルを弄っても改善しないので、DBテーブル以外に原因があるんだろうと調査開始。
大体こういう時は何らかのログが肥大化しているのが定番と思っていたので、/var/log配下でサイズのでかいファイルを探していたところ、/var/log/snmpttでsnmptt.debug-20230126というファイルが更新/肥大化し続けているのを発見した。
#ls -lhS /var/log/snmptt
合計 53GB
-rw-r--r-- 1 snmptt root 53GB 1月 19 15:20 snmptt.debug-20230126 ←追記され続けている
-rw-r--r-- 1 snmptt root 0 1月 26 2023 snmptt.debug ←追記がこちらに行われていない
通常、snmptt.debugは「snmptt.debug」というファイルに書き込まれ、ログローテーションしたタイミングでsnmptt.debug-yyyymmddというファイルになってそこからデータ増加はしないはずなので、明らかにおかしい。
logrotateの実施状況を確認しても、snmptt.debugは空(サイズ0)だから、ローテーションの必要なしとなってしまっている。
#logrotate -d /etc/logrotate.conf
rotating pattern: /var/log/snmptt.debug after 1 days (31 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/snmptt.debug
Now: 2024-01-19 15:20
Last rotated at 2023-01-26 03:11
log does not need rotating (log is empty)
改めて、logrotate設定を確認してみる。
すると、postrotateで指定しているサービス再起動(reload)処理が、古いOS準拠の記載のままであることに気づいた。
#cat /etc/logrotate.d/snmptt
/var/log/snmptt.debug {
# weekly
notifempty
missingok
postrotate
/etc/init.d/snmptt reload >/dev/null 2>/dev/null || true
endscript
}
logrotateとsnmptt.serviceの修正対応
試しに、 /etc/init.d/snmptt reloadを実行しようとすると、「bash: /etc/init.d/snmptt: そのようなファイルやディレクトリはありません」と出てしまう。
systemctl list-unit-files を実行すると、snmpttのサービス自体は存在していた。
#systemctl list-unit-files | grep snmptt
snmptt.service enabled
なので、systemctl reload snmptt.serviceを試みたが、私が利用しているバージョンだとreloadは設定されていなかった。
#systemctl reload snmptt.service
Failed to reload snmptt.service: Job type reload is not applicable for unit snmptt.service
snmptt.orgのサイトを確認すると、v1.5からreloadに対応しているらしい・・・。
実際に最新のsnmptt.serviceをダウンロードして中身を見てみると、「ExecReload=/bin/kill -HUP $MAINPID」が差分として追加されていた。
※下記リンク「Downloads」のsourceforge.netのリンクをクリック→「snmptt」をクリック→「snmptt_1.5」をクリック→「snmptt_1.5.tgz」をダウンロードして展開し、「snmptt.service」の中身を確認
[Unit]
Description=SNMP Trap Translator (SNMPTT)
After=syslog.target network.target snmptrapd.service
[Service]
Type=forking
ExecStart=/usr/sbin/snmptt --daemon
RemainAfterExit=yes
PIDFile=/var/run/snmptt.pid
ExecReload=/bin/kill -HUP $MAINPID
[Install]
WantedBy=multi-user.target
reloadに関しては、この設定以外に追加必要なものはなさそうだったので(というか一般的なreload文だったので)、snmptt.serviceのバージョンアップはせず自分で/lib/systemd/system/snmptt.serviceに「ExecReload=/bin/kill -HUP $MAINPID」を追記した。
systemctl daemon-reloadを実行してUnitの変更を反映させ、改めてsystemctl reload snmptt.serviceを実行したところ、正常にsnmptt.serviceが再起動され、追記ログファイルがsnmptt.debugに変わったことを確認した。
reloadが正常に出来るようになったので、/etc/logrotate.d/snmpttの内容を以下の通り変更する
/var/log/snmptt.debug {
# weekly
notifempty
missingok
postrotate
/bin/systemctl reload snmptt.service > /dev/null 2>/dev/null || true
endscript
}
この状態で、logrotate -d /etc/logrotate.confを行い、snmptt.serviceに関してローテーション実施対象となることを確認。「log is empty」の部分が「log has been rotated at 2024-01-19 3:8, that is not day ago yet」という文言に変わっていた。
ゾンビ化していたsnmpttプロセスの事後処理
翌日、ローテート後もsnmptt.debug-20230126をsnmpttプロセスが離さない(なのでデータ容量が逼迫したまま)事象を確認したため、「lsof | grep snmptt.debug-20230126」で当該プロセスを確認後killし、snmptt.serviceをrestartして正常に処理されるようになった。
参考手順は↓
コメント