Всі ми хочемо дізнаватись про проблеми ще до того, як наш сервер впаде або ускладнить життя користувачам. PostgreSQL дає інструменти для створення сповіщень і запуску задач: pg_notify та pg_cron. Це, по суті, наш особистий будильник і планувальник для бази даних.
Уяви ситуацію: у тебе база даних курсу обміну валют, і раптом один із процесів заблокував інші. Замість того, щоб постійно вручну перевіряти стан бази, можна налаштувати сповіщення, щоб бути в курсі. А для регулярної перевірки стану бази даних стане в пригоді pg_cron. Все це зараз розберемо.
Швидкі сповіщення з бази даних: pg_notify
Почнемо з pg_notify. Це вбудована функція PostgreSQL, яка дозволяє відправляти сповіщення з бази даних у певний "канал". Можеш використовувати її для сигналізації про події, такі як завершення довгих запитів, виявлення блокувань чи інші нестандартні ситуації.
Синтаксис pg_notify досить простий:
NOTIFY <channel>, <message>;
channel— це ім'я каналу, на який відправляється сповіщення.message— рядок із текстом сповіщення.
Наводимо приклад використання pg_notify. Давай створимо сповіщення для випадку, коли знайдено блокування:
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', 'Блокування в базі даних!');
END IF;
END $$;
Цей код перевіряє, чи є необроблене блокування, і відправляє сповіщення у канал alerts.
Щоб слухати сповіщення, використовуй команду LISTEN в іншому підключенні:
LISTEN alerts;
Тепер, якщо pg_notify відправить повідомлення у канал alerts, ти побачиш сповіщення в консолі.
Приклад:
NOTIFY alerts, 'Гей, тут блокування!';
На іншому підключенні, де виконувалось LISTEN alerts, ти одразу отримаєш:
NOTIFY: Гей, тут блокування!
Використання pg_notify не обмежується простими сповіщеннями. Наприклад, можна зв'язати його з тригерами для автоматичних сповіщень про додані, змінені чи видалені дані:
Сповіщення про нові записи
CREATE OR REPLACE FUNCTION notify_new_record()
RETURNS trigger AS $$
BEGIN
PERFORM pg_notify('table_changes', 'Новий запис додано в таблицю!');
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER record_added
AFTER INSERT ON your_table
FOR EACH ROW EXECUTE FUNCTION notify_new_record();
Тепер, якщо у таблицю your_table додається новий запис, ти одразу отримаєш сповіщення.
Детальніше про тригери та вбудовані функції дізнаєшся вже через пару рівнів :P
Типові помилки і як їх уникнути
Якщо ти використовуєш LISTEN, але не бачиш сповіщень, перевір:
- Чи працюєш ти в тому ж з'єднанні, звідки відправляються сповіщення.
- Перевір, чи правильно вказаний канал.
- Переконайся, що ти викликаєш
pg_notifyвсередині транзакції, яка була зафіксована (COMMIT).
Планувальник задач у PostgreSQL: pg_cron
pg_cron — це розширення для PostgreSQL, яке дозволяє виконувати задачі за розкладом, прямо як класичний cron у Linux. Наприклад, можна налаштувати регулярний запуск перевірки блокувань чи збір статистики.
Створення задач із pg_cron
Тепер, коли pg_cron встановлений і готовий до роботи, створимо задачу, яка щодня буде очищати старі записи у таблиці logs.
SELECT cron.schedule('Видалення старих логів',
'0 0 * * *',
$$ DELETE FROM logs WHERE created_at < NOW() - INTERVAL '30 days' $$);
Розкажемо, що тут відбувається:
'0 0 * * *'— це розклад виконання команди (кожного дня опівночі).DELETE FROM logs ...— це SQL-запит, який cron буде виконувати.
Перегляд задач
Щоб побачити всі задачі, які виконуються через pg_cron, використовуй:
SELECT * FROM cron.job;
Вимкнення задач
Вимкнути задачу можна за допомогою:
SELECT cron.unschedule(jobid);
Де jobid — ідентифікатор задачі. Його можна дізнатись із таблиці cron.job.
Корисні приклади з pg_cron
Регулярна перевірка активності запитів
Створимо задачу, яка кожні 5 хвилин перевірятиме довго виконувані запити:
SELECT cron.schedule('Перевірка довгих запитів',
'*/5 * * * *',
$$ SELECT pid, query, state
FROM pg_stat_activity
WHERE state = 'active'
AND now() - query_start > INTERVAL '5 minutes' $$);
Ця задача шукає запити, які виконуються більше 5 хвилин.
Інтеграція із зовнішніми системами
І pg_notify, і pg_cron можна інтегрувати із зовнішніми системами, такими як Slack, Telegram чи системи моніторингу (наприклад, Prometheus).
Telegram
Можеш об'єднати pg_notify із ботом Telegram для відправки сповіщень. Основна ідея — написати скрипт на Python чи іншій мові, який слухає сповіщення і відправляє їх у Telegram.
Приклад простого Python-бота:
import psycopg2
import telegram
# Підключення до PostgreSQL
conn = psycopg2.connect("dbname=your_database user=your_user")
# Створення Telegram-бота
bot = telegram.Bot(token='your_telegram_bot_token')
# Відкриваємо курсор для прослуховування
conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
cur = conn.cursor()
cur.execute("LISTEN alerts;")
# Слухаємо сповіщення
print("Слухаємо сповіщення...")
while True:
conn.poll()
while conn.notifies:
notify = conn.notifies.pop()
print("Отримано сповіщення:", notify.payload)
bot.send_message(chat_id='your_chat_id', text=notify.payload)
Тепер твій бот буде отримувати сповіщення, відправлені через pg_notify.
Коли використовувати pg_notify і pg_cron?
Використовуй pg_notify для миттєвих реакцій (наприклад, сповістити адміністратора про блокування).
Використовуй pg_cron для регулярного виконання задач (перевірка активності запитів, чистка старих даних).
Зауваження та підводні камені
pg_notify генерує сповіщення миттєво, але не зберігає їхню історію. Краще інтегрувати його з файловими логами або зовнішніми системами.
pg_cron може створити неочікуване навантаження, якщо задачі виконуються занадто часто. Завжди тестуй запити перед додаванням їх у розклад.
Тепер ти готовий оптимізувати свій моніторинг і автоматизувати керування базою даних. Вперед — налаштовувати алерти, щоб бути не просто SQL-програмістом, а справжнім DBA!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ