Zabbix’te MySQL ve MariaDB İzleme Yapılandırması

Prodüksiyon ortamında bir MySQL sunucusu sessizce yavaşlarken bunu ancak kullanıcı şikayetleri başladıktan sonra fark etmek… Bu, bir sistem yöneticisinin yaşayabileceği en sinir bozucu senaryolardan biri. Zabbix ile MySQL veya MariaDB izlemeyi düzgün kurduğunuzda, bu tür sorunları kullanıcılar fark etmeden yakalayabilirsiniz. Bu yazıda, temel kurulumdan özel metriklere kadar her şeyi ele alacağız.

Ön Koşullar ve Ortam Hazırlığı

Başlamadan önce şunu netleştirelim: Bu yazı Zabbix 6.x ve üzeri için yazılmıştır. MariaDB 10.5+ ve MySQL 8.0+ ile test edilmiştir. Zabbix Agent 2’nin kurulu olduğunu varsayıyorum çünkü MySQL izleme için Agent 2 çok daha güçlü bir seçenek.

Zabbix Agent 2, Go ile yeniden yazıldığı için MySQL eklentisi native olarak içinde geliyor. Ayrı bir zabbix_agentd.conf ile uğraşmak yerine doğrudan eklenti konfigürasyonu yapabiliyorsunuz.

Monitoring Kullanıcısı Oluşturma

İlk ve en kritik adım, Zabbix’in veritabanına bağlanmak için kullanacağı özel bir kullanıcı oluşturmak. Asla root kullanmayın. Evet, biliyorum, “sadece izleme için” diye düşünüyorsunuz, ama bu hem güvenlik açığı hem de yanlış pratik.

-- MySQL 8.0 için
CREATE USER 'zabbix_monitor'@'localhost' IDENTIFIED BY 'guclu_bir_sifre_123!';
GRANT USAGE ON *.* TO 'zabbix_monitor'@'localhost';
GRANT REPLICATION CLIENT ON *.* TO 'zabbix_monitor'@'localhost';
GRANT PROCESS ON *.* TO 'zabbix_monitor'@'localhost';
GRANT SELECT ON performance_schema.* TO 'zabbix_monitor'@'localhost';
FLUSH PRIVILEGES;

MariaDB kullanıyorsanız sözdizimi biraz farklı olabilir:

-- MariaDB 10.5+ için
CREATE USER 'zabbix_monitor'@'localhost' IDENTIFIED BY 'guclu_bir_sifre_123!';
GRANT USAGE ON *.* TO 'zabbix_monitor'@'localhost';
GRANT REPLICATION CLIENT, PROCESS, SHOW DATABASES ON *.* TO 'zabbix_monitor'@'localhost';
GRANT SELECT ON performance_schema.* TO 'zabbix_monitor'@'localhost';
GRANT SELECT ON mysql.* TO 'zabbix_monitor'@'localhost';
FLUSH PRIVILEGES;

Burada REPLICATION CLIENT yetkisi önemli. Slave durumu metrikleri için bu yetki gerekiyor. Eğer replication kullanmıyorsanız bu satırı atlayabilirsiniz, ama ileride lazım olur diye bırakmanızı öneririm.

Zabbix Agent 2 MySQL Eklentisi Konfigürasyonu

Agent 2 ile MySQL konfigürasyonu /etc/zabbix/zabbix_agent2.conf dosyasında ya da ayrı bir eklenti konfigürasyon dosyasında yapılır. Dağıtıma göre değişmekle birlikte, genellikle /etc/zabbix/zabbix_agent2.d/ dizininde ayrı dosyalar tutmanızı öneririm. Bu sayede yönetimi çok daha temiz oluyor.

# /etc/zabbix/zabbix_agent2.d/mysql.conf dosyasını oluşturun
cat > /etc/zabbix/zabbix_agent2.d/mysql.conf << 'EOF'
Plugins.Mysql.Default.Uri=tcp://localhost:3306
Plugins.Mysql.Default.User=zabbix_monitor
Plugins.Mysql.Default.Password=guclu_bir_sifre_123!
Plugins.Mysql.Default.TLSConnect=disable
EOF

Eğer birden fazla MySQL instance izleyecekseniz (mikroservis mimarilerinde bu çok yaygın), named session tanımlaması yapabilirsiniz:

# Birden fazla instance için
cat >> /etc/zabbix/zabbix_agent2.d/mysql.conf << 'EOF'

# Production DB
Plugins.Mysql.Sessions.proddb.Uri=tcp://localhost:3306
Plugins.Mysql.Sessions.proddb.User=zabbix_monitor
Plugins.Mysql.Sessions.proddb.Password=sifre1

# Analitik DB (farklı port)
Plugins.Mysql.Sessions.analyticdb.Uri=tcp://localhost:3307
Plugins.Mysql.Sessions.analyticdb.User=zabbix_monitor
Plugins.Mysql.Sessions.analyticdb.Password=sifre2
EOF

Konfigürasyon dosyasının izinlerine dikkat edin. Şifre düz metin olarak duruyor, bu yüzden:

chmod 640 /etc/zabbix/zabbix_agent2.d/mysql.conf
chown root:zabbix /etc/zabbix/zabbix_agent2.d/mysql.conf

Agenti yeniden başlatın:

systemctl restart zabbix-agent2
systemctl status zabbix-agent2

Zabbix Arayüzünde Template Bağlama

Zabbix 6.x ile birlikte “MySQL by Zabbix Agent 2” template’i standart olarak geliyor. Arayüzde Configuration > Hosts > [Sunucunuz] > Templates bölümüne gidip bu template’i ekleyebilirsiniz.

Template bağlandıktan sonra iki makro tanımlamanız gerekiyor:

  • {$MYSQL.DSN}: Bağlantı dizesi, örneğin tcp://localhost:3306
  • {$MYSQL.USER}: Kullanıcı adı
  • {$MYSQL.PASSWORD}: Şifre

Bu makroları Configuration > Hosts > [Sunucunuz] > Macros sekmesinden ekleyebilirsiniz.

Template’in bağlantıyı doğru kurduğunu test etmek için komut satırından şunu çalıştırabilirsiniz:

zabbix_agent2 -t mysql.ping[tcp://localhost:3306,zabbix_monitor,guclu_bir_sifre_123!]

Çıktı 1 ise bağlantı başarılı. 0 veya hata geliyorsa önce bağlantı sorununu çözmeniz gerekiyor.

Önemli Metrikler ve Anlamları

Standart template pek çok şeyi izliyor, ama her sysadmin’in özellikle dikkat etmesi gereken birkaç kritik metrik var.

Connections (Bağlantı Sayısı): max_connections değerinizin yüzde kaçını kullandığınıza bakın. Yüzde 80’i geçince alarm verecek şekilde ayarlayın. Ben genellikle uyarıyı yüzde 70’te, kritik alarmı yüzde 85’te kurarım.

Slow Queries: Yavaş sorgu sayısı artıyorsa bu ciddi bir sinyal. long_query_time değerinizin ne olduğuna ve slow_query_log‘un açık olup olmadığına bakın.

InnoDB Buffer Pool Hit Ratio: Bu değer yüzde 95’in altına düşmeye başlarsa RAM’iniz yetersiz demektir. Hedef her zaman yüzde 99 civarında olmalı.

Replication Lag: Master-slave kurulumunuz varsa, slave’in kaç saniye geride olduğunu izleyin. 30 saniyeyi geçen lag’lar operasyonel sorunlara yol açabilir.

Özel Item’lar ve UserParameter Kullanımı

Standart template bazı şeyleri kapsamıyor. Özellikle tablo boyutları, veritabanı bazlı bağlantı istatistikleri veya özel status değişkenleri için UserParameter tanımlamanız gerekiyor.

Zabbix Agent 1 kullanıyorsanız bu yaklaşım hala geçerli:

# /etc/zabbix/zabbix_agentd.d/mysql_custom.conf
cat > /etc/zabbix/zabbix_agentd.d/mysql_custom.conf << 'EOF'
UserParameter=mysql.custom.table_size[*],mysql -u zabbix_monitor -pguclu_bir_sifre_123! -e "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS size_mb FROM information_schema.tables WHERE table_schema='$1';" 2>/dev/null | tail -1
UserParameter=mysql.custom.thread_count,mysql -u zabbix_monitor -pguclu_bir_sifre_123! -e "SHOW STATUS LIKE 'Threads_connected';" 2>/dev/null | awk '{print $2}' | tail -1
UserParameter=mysql.custom.aborted_connects,mysql -u zabbix_monitor -pguclu_bir_sifre_123! -e "SHOW GLOBAL STATUS LIKE 'Aborted_connects';" 2>/dev/null | awk '{print $2}' | tail -1
EOF

Ama komut satırında şifre yazmak kötü bir pratik. Bunun yerine MySQL konfigürasyon dosyası kullanın:

# /etc/zabbix/.my.cnf dosyası oluşturun
cat > /etc/zabbix/.my.cnf << 'EOF'
[client]
user=zabbix_monitor
password=guclu_bir_sifre_123!
host=localhost
EOF

chmod 600 /etc/zabbix/.my.cnf
chown zabbix:zabbix /etc/zabbix/.my.cnf

Sonra UserParameter’larınızı şu şekilde güncelleyin:

UserParameter=mysql.custom.table_size[*],mysql --defaults-file=/etc/zabbix/.my.cnf -e "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) FROM information_schema.tables WHERE table_schema='$1';" 2>/dev/null | tail -1

Gelişmiş İzleme: Özel Script ile Toplu Metrik Toplama

Tek tek UserParameter tanımlamak yerine, bir script yazarak tüm metrikleri tek seferde toplayabilirsiniz. Bu yöntem hem daha verimli hem de veritabanına daha az bağlantı açıyor.

#!/bin/bash
# /usr/local/bin/mysql_zabbix_check.sh

DEFAULTS_FILE="/etc/zabbix/.my.cnf"
METRIC=$1

get_status() {
    mysql --defaults-file=$DEFAULTS_FILE -N -e "SHOW GLOBAL STATUS LIKE '$1';" 2>/dev/null | awk '{print $2}'
}

get_variable() {
    mysql --defaults-file=$DEFAULTS_FILE -N -e "SHOW GLOBAL VARIABLES LIKE '$1';" 2>/dev/null | awk '{print $2}'
}

case "$METRIC" in
    "connections_used_pct")
        MAX=$(get_variable "max_connections")
        CURRENT=$(get_status "Threads_connected")
        if [ -n "$MAX" ] && [ -n "$CURRENT" ] && [ "$MAX" -gt 0 ]; then
            echo "scale=2; ($CURRENT * 100) / $MAX" | bc
        else
            echo "0"
        fi
        ;;
    "innodb_buffer_hit_ratio")
        READS=$(get_status "Innodb_buffer_pool_reads")
        REQUESTS=$(get_status "Innodb_buffer_pool_read_requests")
        if [ -n "$REQUESTS" ] && [ "$REQUESTS" -gt 0 ]; then
            echo "scale=4; (1 - ($READS / $REQUESTS)) * 100" | bc
        else
            echo "0"
        fi
        ;;
    "slave_lag")
        mysql --defaults-file=$DEFAULTS_FILE -e "SHOW SLAVE STATUSG" 2>/dev/null | grep "Seconds_Behind_Master" | awk '{print $2}'
        ;;
    "deadlocks")
        get_status "Innodb_deadlocks"
        ;;
    *)
        echo "Bilinmeyen metrik: $METRIC"
        exit 1
        ;;
esac
chmod +x /usr/local/bin/mysql_zabbix_check.sh

# UserParameter tanımlaması
echo 'UserParameter=mysql.advanced[*],/usr/local/bin/mysql_zabbix_check.sh "$1"' >> /etc/zabbix/zabbix_agentd.d/mysql_custom.conf

Trigger ve Alert Konfigürasyonu

Metrikler toplandıktan sonra anlamlı triggerlar kurmazsanız izlemenin pek bir faydası yok. İşte prodüksiyon ortamlarında kullandığım trigger yapılandırmaları için öneriler:

Bağlantı havuzu kritik seviye: Son 5 dakika boyunca bağlantı kullanımı yüzde 80’i aşıyorsa uyar. Tek anlık spikeleri görmezden gelmek için min() fonksiyonu yerine avg() kullanın.

Slave replication durdu: Slave_IO_Running veya Slave_SQL_Running değeri No ise anında alarm. Bu genellikle kilitlenme ya da ağ kesintisi anlamına gelir.

Çok fazla yavaş sorgu: Son 10 dakikada slow query sayısı dakikada 10’u geçiyorsa bu ciddi bir sorun işareti.

Bağlantı hataları artıyor: Aborted_connects metriği artış gösteriyorsa uygulama tarafında bağlantı sorunları olabilir.

Zabbix arayüzünde trigger oluştururken expression syntax’ına dikkat edin. Zabbix 6.x’te yeni expression formatı kullanılıyor:

avg(/MySQL_Server/mysql.advanced[connections_used_pct],5m)>80

Performans Şeması (Performance Schema) Entegrasyonu

MySQL 8.0 ve MariaDB 10.5+ ile Performance Schema çok daha güçlü hale geldi. Zabbix ile bunu entegre etmek için önce Performance Schema’nın aktif olduğunu doğrulayın:

SHOW VARIABLES LIKE 'performance_schema';
-- Value: ON olmalı

Kapalıysa my.cnf dosyasına ekleyin:

[mysqld]
performance_schema = ON
performance_schema_instrument = 'statement/%=ON'
performance_schema_consumer_events_statements_summary_by_digest=ON

En çok CPU tüketen sorguları Zabbix’e taşımak için bir script yazabilirsiniz:

#!/bin/bash
# En çok kaynak tüketen 5 sorguyu JSON olarak döndür
# Zabbix Low-Level Discovery için kullanılabilir

mysql --defaults-file=/etc/zabbix/.my.cnf -N -e "
SELECT 
    DIGEST_TEXT,
    COUNT_STAR,
    ROUND(AVG_TIMER_WAIT/1000000000, 3) as avg_ms,
    SUM_ROWS_EXAMINED,
    SUM_NO_INDEX_USED
FROM performance_schema.events_statements_summary_by_digest
WHERE SCHEMA_NAME NOT IN ('performance_schema', 'information_schema', 'mysql')
ORDER BY AVG_TIMER_WAIT DESC
LIMIT 5;" 2>/dev/null

Gerçek Dünya Senaryosu: E-Ticaret Sitesinde Kriz

Geçen yıl yaşadığım bir vakayı paylaşmak istiyorum. Büyük bir kampanya günü öncesinde müşterinin MySQL sunucusu izleniyordu ama yalnızca temel metriklerle. Kampanya başladığında bağlantı sayısı tavan yaptı ve max_connections limitine ulaşıldı. Uygulama “Too many connections” hatası vermeye başladı.

Eğer şu metrikler düzgün izlenip triggerlar kurulmuş olsaydı, bu kriz 30-40 dakika önce öngörülebilirdi:

  • Threads_connected / max_connections oranı: Yüzde 60’ta uyarı verseydi, DBA vakitlice max_connections değerini artırabilirdi.
  • Connection errors: Connection_errors_max_connections sayacı artmaya başlamadan önce alarm devreye girebilirdi.
  • Wait events: InnoDB lock wait sayıları artıyordu ama kimse bakmıyordu.

Bu olaydan sonra o müşterinin Zabbix konfigürasyonunu sıfırdan kurdum. Şimdi kampanya günlerinde bir sorun olmadan önce 3-4 uyarı geliyor ve DBA ekibi proaktif müdahale edebiliyor.

MariaDB Galera Cluster İzleme

Eğer MariaDB Galera Cluster kullanıyorsanız, standart MySQL template’i yeterli değil. Cluster’a özgü birkaç kritik metrik daha var:

-- Cluster boyutu
SHOW STATUS LIKE 'wsrep_cluster_size';

-- Node durumu
SHOW STATUS LIKE 'wsrep_local_state_comment';

-- Senkronizasyon durumu
SHOW STATUS LIKE 'wsrep_connected';

-- Flow control (bu değer yüksekse cluster sıkışmış demek)
SHOW STATUS LIKE 'wsrep_flow_control_paused';

Bu metrikleri UserParameter olarak ekleyin:

UserParameter=mysql.galera[*],mysql --defaults-file=/etc/zabbix/.my.cnf -N -e "SHOW STATUS LIKE 'wsrep_$1';" 2>/dev/null | awk '{print $2}'

Zabbix’te şu şekilde item tanımlayabilirsiniz:

  • Key: mysql.galera[cluster_size]
  • Key: mysql.galera[local_state_comment]
  • Key: mysql.galera[flow_control_paused]

wsrep_flow_control_paused değeri 0’ın üzerine çıkmaya başlarsa cluster’da ciddi bir gecikme sorunu var demektir. Bu değer 0.1’i (yüzde 10) geçerse alarm vermenizi öneririm.

İzleme Konfigürasyonunu Otomatikleştirme

Birden fazla sunucu yönetiyorsanız her şeyi tek tek yapmak zaman kaybı. Ansible ile bu kurulumu otomatikleştirebilirsiniz:

# Ansible playbook için temel MySQL monitoring setup
# Sadece kritik komutları gösteriyorum

# 1. Monitoring kullanıcısını oluştur
mysql -u root -p"{{ mysql_root_password }}" << 'EOSQL'
CREATE USER IF NOT EXISTS 'zabbix_monitor'@'localhost' 
  IDENTIFIED BY '{{ zabbix_monitor_password }}';
GRANT USAGE, PROCESS, REPLICATION CLIENT ON *.* 
  TO 'zabbix_monitor'@'localhost';
GRANT SELECT ON performance_schema.* 
  TO 'zabbix_monitor'@'localhost';
FLUSH PRIVILEGES;
EOSQL

# 2. Agent konfigürasyon dosyasını oluştur
cat > /etc/zabbix/zabbix_agent2.d/mysql.conf << EOCONF
Plugins.Mysql.Default.Uri=tcp://localhost:3306
Plugins.Mysql.Default.User=zabbix_monitor
Plugins.Mysql.Default.Password={{ zabbix_monitor_password }}
EOCONF

chmod 640 /etc/zabbix/zabbix_agent2.d/mysql.conf
chown root:zabbix /etc/zabbix/zabbix_agent2.d/mysql.conf
systemctl restart zabbix-agent2

Sorun Giderme

İzleme çalışmıyorsa kontrol edeceğiniz yerler:

Agent loglarına bakın:

tail -f /var/log/zabbix/zabbix_agent2.log | grep -i mysql

Bağlantıyı manuel test edin:

zabbix_agent2 -t mysql.ping[tcp://localhost:3306,zabbix_monitor,sifreniz]

Socket üzerinden bağlantı denemek isterseniz:

zabbix_agent2 -t "mysql.ping[unix:/var/lib/mysql/mysql.sock,zabbix_monitor,sifreniz]"

Firewall veya AppArmor/SELinux bazen Agent 2’nin veritabanına bağlanmasını engeller. SELinux aktifse:

# Zabbix agent'in network bağlantısı açmasına izin ver
setsebool -P zabbix_can_network 1

# Ya da audit loglarına bakıp uygun politikayı oluşturun
ausearch -c 'zabbix_agent2' --raw | audit2allow -M zabbix_mysql
semodule -i zabbix_mysql.pp

Sonuç

Zabbix ile MySQL/MariaDB izleme, tek seferlik bir kurulum değil. Ortamınız büyüdükçe, yeni servisler ekledikçe ve sorunlarla karşılaştıkça konfigürasyonunuzu evriltmeniz gerekiyor. Başlangıç için standart template’i kurun, monitoring kullanıcısını doğru yetkilerle oluşturun ve en kritik metriklere triggerlar ekleyin. Zamanla neyin önemli olduğunu öğrenecek ve kendi ortamınıza özgü izleme senaryoları geliştirmeye başlayacaksınız.

En önemli tavsiyem şu: İzleme sistemini sadece alarm almak için değil, trend analizi için de kullanın. Bir sunucunun bağlantı sayısının her hafta yüzde 5 arttığını görürseniz, kriz gelmeden önce kapasiteyi artırabilirsiniz. Bu proaktif yaklaşım, reaktif kriz yönetiminden her zaman daha değerlidir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir