Hamımız istəyirik ki, serverimiz çökəndən və ya istifadəçilərin həyatını çətinləşdirməzdən əvvəl problemlərdən xəbərimiz olsun. PostgreSQL bizə bildirişlər yaratmaq və tapşırıqları işə salmaq üçün alətlər verir: pg_notify və pg_cron. Bunlar, əslində, database üçün şəxsi zəngli saatımız və planlaşdırıcımızdır.
Təsəvvür elə: səndə valyuta dəyişmə kursunun database-i var və birdən proseslərdən biri qalanlarını bloklayıb. Database-in vəziyyətini daim əl ilə yoxlamaqdansa, bildirişləri qurub hər şeydən xəbərdar ola bilərsən. Database-in vəziyyətini müntəzəm yoxlamaq üçün isə pg_cron köməyə gəlir. Bütün bunları indi izah edəcəyik.
Database-dən tez bildirişlər: pg_notify
Başlayaq pg_notify ilə. Bu, PostgreSQL-in daxili funksiyasıdır və database-dən müəyyən "kanala" bildiriş göndərməyə imkan verir. Onu uzun sorğuların bitməsi, blokların aşkar olunması və ya başqa qeyri-adi hallarda siqnal vermək üçün istifadə edə bilərsən.
pg_notify-nin sintaksisi çox sadədir:
NOTIFY <channel>, <message>;
channel— bildirişin göndərildiyi kanalın adı.message— bildirişin mətnindən ibarət sətir.
pg_notify istifadəsinə nümunə gətirək. Gəlin blok aşkar olunanda bildiriş göndərən kod yazaq:
DO $$
BEGIN
IF EXISTS (
SELECT 1
FROM pg_locks l
JOIN pg_stat_activity a
ON l.pid = a.pid
WHERE NOT l.granted
) THEN
PERFORM pg_notify('alerts', 'Database-də blok aşkarlandı!');
END IF;
END $$;
Bu kod yoxlayır ki, işlənməmiş blok varmı və varsa, alerts kanalına bildiriş göndərir.
Bildirişləri dinləmək üçün başqa bağlantıda LISTEN əmri istifadə et:
LISTEN alerts;
İndi pg_notify alerts kanalına mesaj göndərsə, konsolda bildirişi görəcəksən.
Nümunə:
NOTIFY alerts, 'Ey, burada blok var!';
Başqa bağlantıda, harada ki LISTEN alerts işləyirdi, dərhal belə görəcəksən:
NOTIFY: Ey, burada blok var!
pg_notify istifadəsi təkcə sadə bildirişlərlə məhdudlaşmır. Məsələn, onu trigger-lərlə birləşdirib avtomatik olaraq əlavə olunan, dəyişən və ya silinən məlumatlar barədə xəbərdarlıq edə bilərsən:
Yeni yazılar barədə bildiriş
CREATE OR REPLACE FUNCTION notify_new_record()
RETURNS trigger AS $$
BEGIN
PERFORM pg_notify('table_changes', 'Cədvələ yeni yazı əlavə olundu!');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER record_added
AFTER INSERT ON your_table
FOR EACH ROW EXECUTE FUNCTION notify_new_record();
İndi your_table-a yeni yazı əlavə olunanda dərhal bildiriş alacaqsan.
Trigger-lər və daxili funksiyalar barədə daha ətraflı bir neçə dərsdən sonra öyrənəcəksən :P
Tipik səhvlər və onlardan necə qaçmaq olar
Əgər LISTEN istifadə edirsən, amma bildirişləri görmürsənsə, yoxla:
- Bildiriş göndərilən eyni bağlantıdasanmı.
- Kanal adını düzgün yazmısanmı.
pg_notify-ni commit olunmuş (COMMIT) tranzaksiyada çağırırsanmı.
PostgreSQL-də tapşırıq planlaşdırıcı: pg_cron
pg_cron — PostgreSQL üçün extension-dur və tapşırıqları cədvəl üzrə icra etməyə imkan verir, eynilə Linux-da klassik cron kimi. Məsələn, blokların yoxlanmasını və ya statistikanın toplanmasını müntəzəm işə sala bilərsən.
pg_cron ilə tapşırıq yaratmaq
İndi pg_cron quraşdırılıb və işləməyə hazırdır, gəlin hər gün logs cədvəlində köhnə yazıları silən tapşırıq yaradaq.
SELECT cron.schedule('Köhnə logların silinməsi',
'0 0 * * *',
$$ DELETE FROM logs WHERE created_at < NOW() - INTERVAL '30 days' $$);
Burada nə baş verir:
'0 0 * * *'— əmrin icra olunma cədvəli (hər gün gecə saat 12-də).DELETE FROM logs ...— cron-un icra edəcəyi SQL sorğusudur.
Tapşırıqlara baxış
pg_cron vasitəsilə icra olunan bütün tapşırıqları görmək üçün istifadə et:
SELECT * FROM cron.job;
Tapşırığın söndürülməsi
Tapşırığı söndürmək üçün belə et:
SELECT cron.unschedule(jobid);
Burada jobid — tapşırığın identifikatorudur. Onu cron.job cədvəlindən öyrənə bilərsən.
pg_cron ilə faydalı nümunələr
Sorğuların aktivliyinin müntəzəm yoxlanması
Gəlin hər 5 dəqiqədən bir uzun müddət işləyən sorğuları yoxlayan tapşırıq yaradaq:
SELECT cron.schedule('Uzun sorğuların yoxlanması',
'*/5 * * * *',
$$ SELECT pid, query, state
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > INTERVAL '5 minutes' $$);
Bu tapşırıq 5 dəqiqədən çox işləyən sorğuları tapır.
Xarici sistemlərlə inteqrasiya
Həm pg_notify, həm də pg_cron Slack, Telegram və ya monitorinq sistemləri (məsələn, Prometheus) kimi xarici sistemlərlə inteqrasiya oluna bilər.
Telegram
pg_notify-ni Telegram botu ilə birləşdirib bildiriş göndərə bilərsən. Əsas ideya — Python və ya başqa dildə skript yazıb bildirişləri dinləmək və onları Telegram-a göndərməkdir.
Sadə Python bot nümunəsi:
import psycopg2
import telegram
# PostgreSQL-ə qoşulma
conn = psycopg2.connect("dbname=your_database user=your_user")
# Telegram botun yaradılması
bot = telegram.Bot(token='your_telegram_bot_token')
# Dinləmək üçün cursor açırıq
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
cur = conn.cursor()
cur.execute("LISTEN alerts;")
# Bildirişləri dinləyirik
print("Bildirişləri dinləyirik...")
while True:
conn.poll()
while conn.notifies:
notify = conn.notifies.pop()
print("Bildiriş alındı:", notify.payload)
bot.send_message(chat_id='your_chat_id', text=notify.payload)
İndi botun pg_notify vasitəsilə göndərilən bildirişləri alacaq.
pg_notify və pg_cron nə vaxt istifadə olunmalıdır?
pg_notify-ni ani reaksiya üçün istifadə et (məsələn, blok barədə adminə xəbər vermək).
pg_cron-u isə müntəzəm tapşırıqlar üçün istifadə et (sorğuların aktivliyinin yoxlanması, köhnə məlumatların təmizlənməsi və s.).
Qeydlər və tələlər
pg_notify bildirişləri dərhal yaradır, amma onların tarixçəsini saxlamır. Onu fayl logları və ya xarici sistemlərlə birləşdirmək daha yaxşıdır.
pg_cron tapşırıqlar çox tez-tez işləsə, gözlənilməz yük yarada bilər. Sorğuları cədvələ əlavə etməzdən əvvəl mütləq test et.
İndi database monitorinqini optimallaşdırmağa və idarəni avtomatlaşdırmağa hazırsan. Davam et — alertləri qur, təkcə SQL proqramçısı yox, həm də DBA ol!
GO TO FULL VERSION