«Site yavaş» neredeyse her zaman veritabanına iner. Doğru sırayla yapılırsa kontrol birkaç dakika sürer: önce yavaşlamanın kendisi sırasında görüleni, sonra haftalardır birikeni.

Sorun yaşanırken bakın

Ana kural: en değerli bilgi tam da her şey yavaşken elde edilebilir. MySQL için ilk komut:

sudo mysqladmin processlist
mysql -e 'SHOW FULL PROCESSLIST'

PostgreSQL için:

sudo -u postgres psql -c "SELECT pid, state, wait_event, now()-query_start AS dur, query
FROM pg_stat_activity WHERE state != 'idle' ORDER BY dur DESC;"

Şu anda neyin ve ne kadar süredir çalıştığını görürsünüz. Yanıt genellikle hemen gelir: ağır bir sorgu ötekileri tutuyordur ya da yüz aynı sorgu bir kilidin açılmasını bekliyordur.

Bağlantılar

mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'"
mysql -e "SHOW GLOBAL STATUS LIKE 'Max_used_connections'"
mysql -e "SHOW VARIABLES LIKE 'max_connections'"

Max_used_connections değeri max_connections değerine yaklaşıyorsa uygulama zaman zaman «too many connections» reddi alıyor demektir. Sınırı yükseltmek yapılacak ilk şey değildir: her bağlantı bellek tutar ve zaten belleği kıt bir sunucuda yükseltmek yalnızca takas alanına gidişi hızlandırır. Önce bağlantıların neden serbest bırakılmadığını çıkarın: genellikle uzun bir sorgu ya da uygulama tarafında havuzlamanın olmayışı.

Aynı şeye öteki taraftan bakmak da yararlıdır: bağlantılardaki keskin bir artış, büyüyen popülariteden değil, ağır bir sayfayı döven botlardan da gelebilir — bir arama, bir katalog süzgeci, bir rapor üreteci.

Yavaş sorgular

Bir yavaş sorgu günlüğü olmadan gidilecek başka yer yoktur. MySQL:

SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

Bir gün sonra:

sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

PostgreSQL, postgresql.conf içinde:

log_min_duration_statement = 1000

Ardından, sorgu başına toplam süreyi doğrudan gösteren pg_stat_statements uzantısı:

SELECT calls, round(total_exec_time) AS total_ms, query
FROM pg_stat_statements ORDER BY total_exec_time DESC LIMIT 10;

Dikkat: önemli olan en uzun sorgu değil, toplam süresi en büyük olandır. Dakikada bin kez çalışan 50 milisaniyelik bir sorgu, günde bir kez çalışan on saniyelik bir rapordan daha çok zarar verir.

En sık unutulan ayar

MySQL ve MariaDB için bu, InnoDB arabellek havuzu boyutudur. Varsayılan 128 megabayttır ve onlarca yıldır değişmemiştir. Veritabanının birkaç gigabayt yer kapladığı bir sunucuda bu, bellekten değil sürekli diskten okuma demektir.

mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size'"

Adanmış bir veritabanı sunucusu için makul ölçüt RAM’in yarısıdır; ayrıca web sunucusu ve PHP çalıştıran bir sunucu için dörtte biri, takasa başlamamaya dikkat ederek. Bu tek ayar, genellikle bir haftalık sorgu iyileştirmesinden daha çoğunu verir.

Diski sessizce yiyen iki şey

MySQL ikili günlükleri. Çoğaltma ve zaman noktasına geri dönüş için gereklidirler, sürekli büyürler ve varsayılan olarak bazen hiç silinmezler. Kontrol için:

sudo du -sh /var/lib/mysql/*bin.*
mysql -e "SHOW VARIABLES LIKE 'binlog_expire_logs_seconds'"

Çoğaltmanız yoksa ve zaman noktasına geri dönüş kullanmıyorsanız saklama süresini makul birkaç güne ayarlayın.

Unutulmuş bir çoğaltma yuvası olan PostgreSQL WAL dosyaları. Daha az bilinen ve daha tehlikeli bir durum: bir çoğaltma yuvası varsa ama tüketicisi artık bağlanmıyorsa, PostgreSQL bağlantının kesilmesinden bu yana her günlüğü saklamak zorundadır — ve disk dolana kadar saklar.

sudo -u postgres psql -c "SELECT slot_name, active, restart_lsn FROM pg_replication_slots;"

Kimsenin ihtiyaç duymadığı etkin olmayan bir yuva kaldırılmalıdır. Bir veritabanının diski garantili biçimde sıfıra indirdiği ender durumlardan biridir.

Boyut ve büyüme

SELECT table_schema, round(sum(data_length+index_length)/1024/1024) AS mb
FROM information_schema.tables GROUP BY table_schema ORDER BY mb DESC;

Faydalı olan güncel rakamdan çok, onun değişme hızıdır. Trafikte buna karşılık gelen bir artış olmadan bir ayda ikiye katlanan bir veritabanı, genellikle yazılan ve hiç temizlenmeyen bir günlükleme tablosu demektir — oturumlar, görev geçmişi, bir eklentinin olay günlüğü.

İki satırda güvenlik

Hazır veritabanı konsolu açıkken iki şeyi kontrol etmeye değer. Birincisi, veritabanına dışarıdan erişilip erişilemediği (ss -tulpn | grep 3306): neredeyse hiçbir zaman dışarıya bakmamalıdır. İkincisi, herhangi bir adresten bağlanabilen hesaplar:

mysql -e "SELECT user, host FROM mysql.user"

host = '%' olan girdiler «her yerden bağlantı» demektir. Port da açıksa, veritabanıyla internet arasında duran tek şey bir paroladır.

Yedekler

Son bir şey. Bir yedek dosyasının varlığı hiçbir şeyi garanti etmez; yalnızca test edilmiş bir geri yükleme eder. Hiç geri yüklenmemiş bir dökümün budanmış çıkması, bir kilitleme hatasıyla alınmış olması ya da yanlış veritabanını içermesi eşit derecede olasıdır. Bunun önceden ve ayrı bir makinede kontrol edilmesi gerekir, kopyaya ihtiyaç duyulan gün değil.

Günlük izleme için üç rakam yeter: bağlantı sayısı, günlük yavaş sorgu sayısı ve veritabanının boyutu. Üçü de yavaş ve öngörülebilir biçimde değişir ve birindeki keskin bir hareket bakmaya değerdir. Bunların tek sayfada nasıl göründüğü aşağıdaki demoda.