CodeGym /Kursy /SQL SELF /Konfiguracja alertów i powiadomień przy problemach

Konfiguracja alertów i powiadomień przy problemach

SQL SELF
Poziom 46 , Lekcja 1
Dostępny

Każdy z nas chce wiedzieć o problemach zanim nasz serwer padnie albo zacznie utrudniać życie użytkownikom. PostgreSQL daje nam narzędzia do tworzenia powiadomień i uruchamiania zadań: pg_notify i pg_cron. To taki nasz prywatny budzik i scheduler dla bazy danych.

Wyobraź sobie sytuację: masz bazę danych kursu wymiany walut i nagle jeden z procesów zablokował resztę. Zamiast ciągle ręcznie sprawdzać stan bazy, możesz ustawić powiadomienia, żeby być na bieżąco. A do regularnego sprawdzania stanu bazy przyda się pg_cron. Zaraz wszystko ogarniemy.

Szybkie powiadomienia z bazy danych: pg_notify

Zaczynamy od pg_notify. To wbudowana funkcja PostgreSQL, która pozwala wysłać powiadomienie z bazy do konkretnego "kanału". Możesz jej użyć do sygnalizowania zdarzeń, takich jak zakończenie długich zapytań, wykrycie blokad albo innych nietypowych sytuacji.

Składnia pg_notify jest całkiem prosta:

NOTIFY <channel>, <message>;
  • channel — nazwa kanału, na który wysyłane jest powiadomienie.
  • message — tekst powiadomienia.

Przykład użycia pg_notify. Zróbmy powiadomienie na wypadek wykrycia blokady:

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', 'Blokada w bazie danych!');
    END IF;
END $$;

Ten kod sprawdza, czy jest jakaś nieprzyznana blokada i wysyła powiadomienie na kanał alerts.

Żeby nasłuchiwać powiadomień, użyj komendy LISTEN w innym połączeniu:

LISTEN alerts;

Teraz, jeśli pg_notify wyśle wiadomość na kanał alerts, zobaczysz powiadomienie w konsoli.

Przykład:

NOTIFY alerts, 'Hej, tu blokada!';

Na innym połączeniu, gdzie było LISTEN alerts, od razu dostaniesz:
NOTIFY: Hej, tu blokada!

Zastosowanie pg_notify nie kończy się na prostych powiadomieniach. Możesz go połączyć z triggerami, żeby automatycznie informować o dodanych, zmienionych lub usuniętych danych:

Powiadomienie o nowych rekordach

CREATE OR REPLACE FUNCTION notify_new_record()
RETURNS trigger AS $$
BEGIN
    PERFORM pg_notify('table_changes', 'Nowy rekord dodany do tabeli!');
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER record_added
AFTER INSERT ON your_table
FOR EACH ROW EXECUTE FUNCTION notify_new_record();

Teraz, jeśli do tabeli your_table zostanie dodany nowy rekord, od razu dostaniesz powiadomienie.

Więcej o triggerach i funkcjach wbudowanych poznasz już za kilka poziomów :P

Typowe błędy i jak ich unikać

Jeśli używasz LISTEN, ale nie widzisz powiadomień, sprawdź:

  1. Czy pracujesz na tym samym połączeniu, z którego wysyłane są powiadomienia.
  2. Czy dobrze podałeś nazwę kanału.
  3. Czy wywołujesz pg_notify wewnątrz transakcji, która została zatwierdzona (COMMIT).

Scheduler zadań w PostgreSQL: pg_cron

pg_cron to rozszerzenie do PostgreSQL, które pozwala wykonywać zadania według harmonogramu, zupełnie jak klasyczny cron w Linuksie. Na przykład możesz ustawić regularne sprawdzanie blokad albo zbieranie statystyk.

Tworzenie zadań z pg_cron

Gdy pg_cron jest już zainstalowany i gotowy do pracy, stwórzmy zadanie, które codziennie będzie czyścić stare rekordy w tabeli logs.

SELECT cron.schedule('Usuwanie starych logów',
'0 0 * * *',
$$ DELETE FROM logs WHERE created_at < NOW() - INTERVAL '30 days' $$);

Co tu się dzieje:

  • '0 0 * * *' — to harmonogram wykonania polecenia (codziennie o północy).
  • DELETE FROM logs ... — to SQL, który cron będzie wykonywał.

Podgląd zadań

Żeby zobaczyć wszystkie zadania wykonywane przez pg_cron, użyj:

SELECT * FROM cron.job;

Wyłączanie zadań

Wyłączyć zadanie możesz przez:

SELECT cron.unschedule(jobid);

Gdzie jobid — to identyfikator zadania. Możesz go znaleźć w tabeli cron.job.

Przydatne przykłady z pg_cron

Regularne sprawdzanie aktywności zapytań

Stwórzmy zadanie, które co 5 minut sprawdza długo trwające zapytania:

SELECT cron.schedule('Sprawdzanie długich zapytań',
'*/5 * * * *',
$$ SELECT pid, query, state
    FROM pg_stat_activity
    WHERE state = 'active'
        AND now() - query_start > INTERVAL '5 minutes' $$);

To zadanie szuka zapytań, które trwają dłużej niż 5 minut.

Integracja z zewnętrznymi systemami

Zarówno pg_notify, jak i pg_cron możesz zintegrować z zewnętrznymi systemami, jak Slack, Telegram czy systemy monitoringu (np. Prometheus).

Telegram

Możesz połączyć pg_notify z botem Telegram do wysyłania powiadomień. Główna idea — napisać skrypt w Pythonie lub innym języku, który nasłuchuje powiadomień i wysyła je do Telegrama.

Przykład prostego bota w Pythonie:

import psycopg2
import telegram

# Połączenie z PostgreSQL
conn = psycopg2.connect("dbname=your_database user=your_user")

# Tworzenie bota Telegram
bot = telegram.Bot(token='your_telegram_bot_token')

# Otwieramy cursor do nasłuchiwania
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
cur = conn.cursor()
cur.execute("LISTEN alerts;")

# Nasłuchujemy powiadomień
print("Nasłuchujemy powiadomień...")
while True:
    conn.poll()
    while conn.notifies:
        notify = conn.notifies.pop()
        print("Odebrano powiadomienie:", notify.payload)
        bot.send_message(chat_id='your_chat_id', text=notify.payload)

Teraz twój bot będzie dostawał powiadomienia wysłane przez pg_notify.

Kiedy używać pg_notify i pg_cron?

Używaj pg_notify do natychmiastowych reakcji (np. powiadom admina o blokadach).

Używaj pg_cron do regularnego wykonywania zadań (sprawdzanie aktywności zapytań, czyszczenie starych danych).

Uwagi i pułapki

pg_notify generuje powiadomienia natychmiast, ale nie przechowuje ich historii. Lepiej zintegrować go z logami plikowymi albo zewnętrznymi systemami.

pg_cron może wywołać nieoczekiwane obciążenie, jeśli zadania są wykonywane zbyt często. Zawsze testuj zapytania przed dodaniem ich do harmonogramu.

Teraz jesteś gotowy, żeby zoptymalizować swój monitoring i zautomatyzować zarządzanie bazą danych. Do dzieła — ustawiaj alerty i bądź nie tylko SQL-programistą, ale prawdziwym DBA!

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION