JavaRush /Курси /SQL SELF /Аналіз поточних запитів і транзакцій

Аналіз поточних запитів і транзакцій

SQL SELF
Рівень 55 , Лекція 4
Відкрита

Давай почнемо з бази. PostgreSQL дає крутий набір інструментів для аналізу SQL-запитів і транзакцій. Наприклад, вбудовані функції current_query() та txid_current() дають тобі можливість:

  • Отримати поточний виконуваний SQL-запит.
  • Дізнатися, в рамках якої транзакції виконується запит.
  • Логувати SQL-операції для подальшого аналізу.
  • Відслідковувати проблеми з транзакціями, якщо твій код очікує одне, а відбувається зовсім інше.

Це все може виручити тебе в ситуаціях, коли стандартний дебаг не допомагає або коли ти хочеш аналізувати поведінку запитів "по слідах".

Огляд вбудованих функцій

Функція current_query()

current_query() повертає текст поточного SQL-запиту, який виконується в цьому з'єднанні. "Звідки воно знає?" — спитаєш ти. PostgreSQL круто відслідковує стан кожного з'єднання, і ця функція допомагає зазирнути в це "закулісся".

Синтаксис:

SELECT current_query();

Приклад виконання:

-- Виконуємо запит у функції
DO $$
BEGIN
    RAISE NOTICE 'Поточний запит: %', current_query();
END;
$$;

-- Результат:
-- NOTICE: Поточний запит: DO $$ BEGIN RAISE NOTICE 'Поточний запит: %', current_query(); END; $$;

Як видно з прикладу, current_query() підказує нам текст виконуваного запиту. Ця інфа дуже корисна для аналізу складних процедур: ти знаєш, що саме виконується прямо зараз!

Функція txid_current()

Коли справа доходить до транзакцій, функція txid_current() стає просто фантастичним інструментом. Вона повертає унікальний ідентифікатор поточної транзакції. Це особливо корисно, якщо ти хочеш відслідкувати послідовність операцій в рамках однієї транзакції.

Синтаксис:

SELECT txid_current();

Приклад виконання:

BEGIN;

-- Отримання ID поточної транзакції
SELECT txid_current();

-- Вивід:
-- 564 (наприклад, ідентифікатор)

-- Завершуємо транзакцію
COMMIT;

Ці транзакційні ID можна використовувати для співставлення логів, аналізу послідовності дій і навіть дебагу багатокористувацьких систем.

Приклади використання в реальних задачах

  1. Логування поточного запиту в процесі виконання.

Іноді процедура або функція містить купу SQL-запитів. Щоб зрозуміти, де щось пішло не так, можна включити логування поточного SQL-запиту. Наприклад:

DO $$
DECLARE
    current_txn_id BIGINT;
BEGIN
    current_txn_id := txid_current();
    RAISE NOTICE 'ID поточної транзакції: %', current_txn_id;

    RAISE NOTICE 'Поточний запит: %', current_query();

    -- Тут могли б бути твої додаткові операції
END;
$$;

Цей код виведе в консоль ідентифікатор транзакції і текст поточного запиту. Тепер ми можемо точно знати, що виконується прямо зараз.

  1. Аналіз транзакцій для виявлення проблем.

Уяви сценарій, коли користувачі скаржаться на втрату даних при масовому оновленні. Ти створюєш кілька процедур, кожна з яких запускається всередині однієї транзакції. Як зрозуміти, хто винен? Ось приклад:

BEGIN;

-- Додаємо логування транзакції
DO $$
BEGIN
    RAISE NOTICE 'ID поточної транзакції: %', txid_current();
END;
$$;

-- Виконуємо "проблемний" SQL-запит
UPDATE orders
SET status = 'processed'
WHERE id IN (SELECT order_id FROM pending_orders);

COMMIT;

Якщо оновлення не проходять, ти одразу бачиш ID транзакції, до якої відносяться твої зміни. Це не тільки спрощує пошук помилки, а й допомагає зрозуміти, чи були конфлікти транзакцій.

  1. Логування запитів для історичного аналізу.

Іноді треба не тільки виправити поточну проблему, а й запам'ятати, які SQL-запити виконувались. Наприклад, ти можеш створити таблицю для логування:

CREATE TABLE query_log (
    log_time TIMESTAMP DEFAULT NOW(),
    query_text TEXT,
    txn_id BIGINT
);

Ось як можна записувати запити з використанням current_query() і txid_current():

DO $$
BEGIN
    INSERT INTO query_log (query_text, txn_id)
    VALUES (current_query(), txid_current());
END;
$$;

Тепер у таблиці query_log зберігається інфа про кожен виконаний запит і транзакцію, в якій він був виконаний. Це безцінний інструмент для аналізу роботи бази даних.

Практичні кейси використання

Приклад 1: аудит транзакцій

Уяви, що ти аналізуєш операції в багатокористувацькій системі. Логування транзакційного ID (txid_current) дозволяє тобі групувати дії по одній транзакції.

DO $$
DECLARE
    txn_id BIGINT;
BEGIN
    txn_id := txid_current();
    RAISE NOTICE 'Транзакція почалась з ID: %', txn_id;

    -- Якась операція
    UPDATE users SET last_login = NOW() WHERE id = 123;

    RAISE NOTICE 'Поточний запит: %', current_query();
END;
$$;

Приклад 2: спрощення дебагу процедур

Ти викликав складну процедуру, і щось пішло не так. Ти можеш вбудувати логування current_query() на різних етапах функції, щоб бачити, який запит виконувався:

CREATE OR REPLACE FUNCTION debugged_function() RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Поточний запит до оновлення: %', current_query();
    UPDATE data_table SET field = 'debugging';
    RAISE NOTICE 'Поточний запит після оновлення: %', current_query();
END;
$$ LANGUAGE plpgsql;

Коли виклик функції завершиться, ти отримаєш два повідомлення з відповідними SQL-запитами.

Поради по застосуванню

  1. Використовуй current_query() для логування запитів всередині багатокористувацьких систем, щоб розуміти, які дії виконуються.
  2. txid_current() ідеально підходить для аналізу походження змін: на якому етапі твоєї транзакції дані були додані або змінені.
  3. Не забувай видаляти непотрібне логування, коли закінчиш його використовувати. Постійні повідомлення через RAISE NOTICE можуть сповільнити виконання твоєї функції.

Ці вбудовані функції — твій "мікроскоп", який дозволяє досліджувати найдрібніші деталі того, як працює база даних. Вони допоможуть тобі ловити баги, покращувати продуктивність і розуміти, що відбувається в складних системах. Десь там, всередині PostgreSQL, твоя база вже готова ділитися секретами — залишилось тільки навчитись їх читати.

1
Опитування
Vstup do vidladky PL/pgSQL, рівень 55, лекція 4
Недоступний
Vstup do vidladky PL/pgSQL
Vstup do vidladky PL/pgSQL
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ