CodeGym /Cursos /SQL SELF /Análise de queries e transações atuais

Análise de queries e transações atuais

SQL SELF
Nível 55, Lição 4
Disponível

Bora começar do básico. O PostgreSQL tem um monte de ferramenta massa pra analisar queries SQL e transações. Por exemplo, as funções nativas current_query() e txid_current() te dão a chance de:

  • Pegar a query SQL que tá rodando agora.
  • Saber em qual transação a query tá sendo executada.
  • Logar operações SQL pra analisar depois.
  • Rastrear problemas com transações, tipo quando seu código espera uma coisa, mas acontece outra totalmente diferente.

Tudo isso pode te salvar quando o output padrão de debug não resolve ou quando você quer analisar o comportamento das queries "no rastro".

Visão geral das funções nativas

Função current_query()

current_query() retorna o texto da query SQL que tá rolando na conexão atual. "Como ela sabe disso?" — você pode perguntar. O PostgreSQL monitora direitinho o estado de cada conexão, e essa função deixa você dar uma espiada nesse "bastidor".

Sintaxe:

SELECT current_query();

Exemplo de execução:

-- Rodando a query dentro de uma função
DO $$
BEGIN
    RAISE NOTICE 'Query atual: %', current_query();
END;
$$;

-- Resultado:
-- NOTICE: Query atual: DO $$ BEGIN RAISE NOTICE 'Query atual: %', current_query(); END; $$;

Como dá pra ver no exemplo, current_query() mostra pra gente o texto da query que tá sendo executada. Essa info é muito útil pra analisar procedures complicadas: você sabe exatamente o que tá rolando naquele momento!

Função txid_current()

Quando o papo é transação, a função txid_current() é uma ferramenta animal. Ela retorna um identificador único da transação atual. Isso é top se você quiser rastrear a sequência de operações dentro de uma transação só.

Sintaxe:

SELECT txid_current();

Exemplo de execução:

BEGIN;

-- Pegando o ID da transação atual
SELECT txid_current();

-- Saída:
-- 564 (por exemplo, o identificador)

-- Finalizando a transação
COMMIT;

Esses IDs de transação podem ser usados pra cruzar logs, analisar a ordem das ações e até debugar sistemas multiusuário.

Exemplos de uso em tarefas reais

  1. Logando a query atual durante a execução.

Às vezes uma procedure ou função tem um monte de queries SQL. Pra sacar onde deu ruim, dá pra ligar o log da query SQL atual. Tipo assim:

DO $$
DECLARE
    current_txn_id BIGINT;
BEGIN
    current_txn_id := txid_current();
    RAISE NOTICE 'ID da transação atual: %', current_txn_id;

    RAISE NOTICE 'Query atual: %', current_query();

    -- Aqui poderiam rolar suas operações extras
END;
$$;

Esse código vai mostrar no console o ID da transação e o texto da query atual. Agora dá pra saber certinho o que tá rodando naquele instante.

  1. Analisando transações pra achar problemas.

Imagina um cenário onde a galera reclama de perda de dados num update em massa. Você cria várias procedures, cada uma rodando dentro de uma transação. Como descobrir o culpado? Olha só:

BEGIN;

-- Logando a transação
DO $$
BEGIN
    RAISE NOTICE 'ID da transação atual: %', txid_current();
END;
$$;

-- Rodando a query "problemática"
UPDATE orders
SET status = 'processed'
WHERE id IN (SELECT order_id FROM pending_orders);

COMMIT;

Se os updates não rolarem, você já vê na hora o ID da transação que tá mexendo nos dados. Isso não só facilita achar o erro, mas também ajuda a entender se rolou conflito de transação.

  1. Logando queries pra análise histórica.

Às vezes você não quer só corrigir o problema atual, mas também guardar quais queries SQL foram executadas. Por exemplo, dá pra criar uma tabela de log:

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

Olha como dá pra registrar as queries usando current_query() e txid_current():

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

Agora na tabela query_log fica salvo o que foi executado e em qual transação. Isso é uma mão na roda pra analisar o que tá rolando no banco.

Casos práticos de uso

Exemplo 1: auditoria de transações

Imagina que você tá analisando operações num sistema multiusuário. Logar o ID da transação (txid_current) deixa você agrupar ações por transação.

DO $$
DECLARE
    txn_id BIGINT;
BEGIN
    txn_id := txid_current();
    RAISE NOTICE 'Transação começou com ID: %', txn_id;

    -- Alguma operação
    UPDATE users SET last_login = NOW() WHERE id = 123;

    RAISE NOTICE 'Query atual: %', current_query();
END;
$$;

Exemplo 2: debug mais fácil de procedures

Você chamou uma procedure complicada e deu ruim. Dá pra colocar log com current_query() em vários pontos da função pra ver qual query tava rodando:

CREATE OR REPLACE FUNCTION debugged_function() RETURNS VOID AS $$
BEGIN
    RAISE NOTICE 'Query atual antes do update: %', current_query();
    UPDATE data_table SET field = 'debugging';
    RAISE NOTICE 'Query atual depois do update: %', current_query();
END;
$$ LANGUAGE plpgsql;

Quando a função terminar, você recebe dois avisos com as queries correspondentes.

Dicas de uso

  1. Use current_query() pra logar queries dentro de sistemas multiusuário e entender o que tá rolando.
  2. txid_current() é perfeito pra analisar de onde veio uma alteração: em que ponto da transação os dados foram inseridos ou mudados.
  3. Não esquece de tirar o log quando não precisar mais. Ficar mandando RAISE NOTICE toda hora pode deixar sua função mais lenta.

Essas funções nativas são tipo um "microscópio" pra você investigar os detalhes do que acontece no banco. Elas vão te ajudar a caçar bugs, melhorar performance e entender o que tá rolando em sistemas complexos. Lá dentro do PostgreSQL, seu banco já tá pronto pra contar os segredos — só falta você aprender a ler.

2
Tarefa
SQL SELF, nível 55, lição 4
Bloqueado
Obtendo a consulta atual usando `current_query()`
Obtendo a consulta atual usando `current_query()`
1
Pesquisa/teste
Introdução à depuração em PL/pgSQL, nível 55, lição 4
Indisponível
Introdução à depuração em PL/pgSQL
Introdução à depuração em PL/pgSQL
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION