Hlavní navigace

ZABBIX a neočekávaný nárůst velikosti databáze

11. 9. 2023 9:12 (aktualizováno) Zdeněk Spíchal


Rád bych se s Vámi podělil o jeden zajímavý problém a jeho řešení týkající se rychlého a velkého nárůstu dat v databázi monitorovacího nástroje ZABBIX.

Na začátku příběhu byla migrace celého monitoring prostředí ze stávající on-premise instalace do Microsoft Azure cloudu v rámci sjednocení, centralizace, standardizace a dalších důvodů.
Sjednocení a centralizace znamená kromě jiného také migraci samostatných Zabbix instancí do jediné.
Tato fáze započala ještě před přesunem na Azure.

Vše proběhlo bez větších problémů a postupně došlo k aktivaci a přidávání dalších projektů a opět bez větších problémů.
Zničehonic však začala znatelně narůstat velikost databáze – a to ne postupně (ať už lineárně či exponenciálně), ale skokově vždy v čase od osmi do deseti hodin večer, ale nepravidelně co se týká dnů.

Z počátku bylo pozorované chování přisuzováno plnění tabulky historie vždy po přidání projektu a nebyla mu věnována přílišná pozornost, ale po té, co velikost překročila určitou mez odvozenou od původní instalace a množství měření, dále vzhledem k začínajícím problémům se zobrazováním a odezvou a začínajícími obavami o funkčnost jsem začal problém podrobně sledovat a analyzovat.

To probíhalo běžným způsobem, porovnáním kdy a jak se vyskytují skokové nárůsty a snahou zjistit s čím to může mít souvislost.
Zároveň proběhla revize všech používaných šablon a další optimalizace.

Bohužel nárůsty se vyskytovaly dále a nejhorší byla jejich nepravidelnost.
Drobnou chybou bylo, že jsem se hned zkraje zapomenul podívat, kde dochází ke skutečnému nárůstu dat. Naštěstí jsem se nakonec podíval a bylo jasné, ze je problém s auditlog tabulkou.

Nová otázka byla, proč se tak děje.

Podařilo se zjistit, že v důsledku rebuildování testovacích prostředí na Kubernetes jednoho z projektů dochází k cca 5000 zápisům změn za minutu během celého procesu do auditlogu pod uživatelem SYSTEM. To vedlo k ohromným nárůstům velikosti tabulky.

Dobře, máme zdroj problému, nicméně řešení nevypadalo úplně jednoduše.
Samozřejmě můžete přijít s jednoduchým způsobem jak se zbavit těchto logů, ale jen celkově.

V tomto multitenant prostředí s mnoha uživateli a administrátory jednotlivých projektů s různým oprávněním je rozhodně snahou udržet prostředí v chodu a mít možnost v případě problému vždy dohledat kdo a co změnil.

Takže řešení v podobě nastavení času pro uchovávání dat pro všechny auditlogy v GUI Zabbixu nepřipadalo v úvahu. Bohužel zde není možnost nastavení zvlášť pro SYSTEM a ostatní uživatele.

Bylo potřeba najít vhodnější řešení a tak jsem se vrátil k základům a šel se podívat co by šlo nastavit na úrovni databáze.
Prohlédnul jsem si jak se data ukládají a udělal několik testů pro výběr dat a sestavil jednoduchou SQL úlohu pro odmazávání dat na základě toho kdo je vygeneroval a času jejich zápisu.
Kdo je vygeneroval bylo jasné a čas byl určován jako starší než aktuální čas mínus počet dní, pro které se měla data zachovat.
Následovalo postupné odmazávání historických dat, vždy se zmenšoval počet dní.

Operace byla provedena postupně z důvodu přílišné zátěže a času potřebném pro provedení.

Chvíli to trvalo, ale výsledek se dostavil.

Následně byl vytvořen skript pro pravidelné automatické odmazávání těchto vybraných dat při zvolené retenci.
Skript je spouštěn každých 24 hodin posunutých o 12 hodin na dvou aplikačních serverech Zabbixu konfigurovaných v HA.
Na obou instancích proto, aby byla zaručena funkčnost i při výpadku a posunutí proto, aby nedošlo k souběhu.

Řešení funguje skvěle, data se správně odmazávají, můžeme tak držet rozdílnou dobu auditlogu pro systémové a skutečné uživatele.


Zde přikládám jednotlivé příkazy a nastavení

auditlog_clean.sh

#!/bin/bash

#database connection
DBUser="user"
DBPassword="heslo"

echo $(date) >> /etc/zabbix/cleaning/auditlog_clean.log

#period define history time in seconds to keep data
period=1296000
echo $period >> /etc/zabbix/cleaning/auditlog_clean.log

#check actual unixtime in seconds
actualtime=$(date +%s)
echo $actualtime >> /etc/zabbix/cleaning/auditlog_clean.log

deletetime=$((actualtime - period))
echo $deletetime >> /etc/zabbix/cleaning/auditlog_clean.log

#SQL task to delete all data for System user in zabbix auditlog table older than deletetime
sql_task="delete
from zabbix.auditlog where username='System' and clock < $deletetime;"
sql_task_status=$(mysql -h -p3306 zabbix -u$DBUser -p$DBPassword -e "$sql_task" >> /etc/zabbix/cleaning/auditlog_clean.log)


crontab

#zabbix database clean auditlog table
1 18 * * *  sh /etc/zabbix/cleaning/auditlog_clean.sh
#zabbix database clean auditlog table
1 6 * * *  sh /etc/zabbix/cleaning/auditlog_clean.sh


SQL úloha pro zjištění počtu záznamů

select count(*) from table where username='System' and clock $deletetime;"


SQL úloha pro smazání všech záznamů usera System a starších než …

delete from zabbix.auditlog where username="System" and clock < "deletetime";


SQL úloha pro zjištění velikosti a volného místa tří největších tabulek databáze zabbix v MB

select table_name,round(data_length/1024/1024),round(data_free/1024/1024)
from information_schema.tables where table_schema='zabbix'
order by data_free desc limit 3;


Informace o velikosti Zabbix instance

Sdílet