

# Rastreamento de consultas distribuído em logs do PostgreSQL no Aurora PostgreSQL Limitless Database
<a name="limitless-query.tracing"></a>

O rastreamento de consultas distribuído é uma ferramenta para rastrear e correlacionar consultas em logs do PostgreSQL no Aurora PostgreSQL Limitless Database. No Aurora PostgreSQL, é possível usar o ID da transação para identificar uma transação. Mas no Aurora PostgreSQL Limitless Database, o ID da transação pode se repetir em vários roteadores. Portanto, recomendamos usar o ID de rastreamento no Limitless Database.

Os principais casos de uso são:
+ Usar a função `rds_aurora.limitless_get_last_trace_id()` para encontrar o ID de rastreamento exclusivo da última consulta executada na sessão atual. Em seguida, pesquisar o grupo de logs do cluster de banco de dados no Amazon CloudWatch Logs usando esse ID de rastreamento para encontrar todos os logs relacionados.

  Você pode usar os parâmetros `log_min_messages` e `log_min_error_statement` em conjunto para controlar o volume de logs impressos e imprimir uma declaração que contenha o ID de rastreamento.
+ Use o parâmetro `log_min_duration_statement` para determinar o tempo de execução acima do qual todas as consultas imprimem sua duração de execução e ID de rastreamento. Esse tempo de execução pode então ser pesquisado no grupo de logs do cluster de banco de dados no CloudWatch Logs para ajudar a determinar os nós de gargalo e os esforços de otimização do planejador.

  O parâmetro `log_min_duration_statement` habilita o ID de rastreamento para todos os nós, independentemente dos valores dos parâmetros `log_min_messages` e `log_min_error_statement`.

**Topics**
+ [ID de rastreamento](#limitless-query.tracing.ID)
+ [Usar o rastreamento de consultas](#limitless-query.tracing.using)
+ [Exemplos de log](#limitless-query.tracing.examples)

## ID de rastreamento
<a name="limitless-query.tracing.ID"></a>

O ponto central deste recurso é um identificador exclusivo conhecido como *ID de rastreamento*. O ID de rastreamento é uma string de 31 dígitos anexada às linhas de log STATEMENT dos logs do PostgreSQL, que atua como um identificador preciso para correlacionar logs relacionados à execução de uma consulta específica. Os exemplos são `1126253375719408504000000000011` e `1126253375719408495000000000090`.

O ID de rastreamento é composto pelo seguinte:
+ Identificador da transação: os primeiros 20 dígitos, que identificam a transação de forma exclusiva.
+ Identificador de comando: os primeiros 30 dígitos, que indicam uma consulta individual em uma transação.

  Se mais de 4.294.967.294 consultas forem executadas dentro de um bloco de transação explícito, o identificador de comando retorna para `1`. Quando isso acontece, você recebe uma notificação pela seguinte mensagem de `LOG` no log do PostgreSQL:

  ```
  wrapping around the tracing ID back to 1 after running 4294967294 (4.2 billion or 2^32-2) queries inside of an explicit transaction block
  ```
+ Identificador do tipo de nó: o último dígito, que indica se o nó está funcionando como um roteador coordenador (`1`) ou um nó participante (`0`).

Os seguintes exemplos ilustram os componentes do ID de rastreamento:
+ `1126253375719408504000000000011`:
  + Identificador da transação: `1126253375719408504`
  + Identificador de comando: `112625337571940850400000000001` indica o primeiro comando no bloco de transação
  + Identificador do tipo de nó: `1` indica um roteador coordenador
+ `1126253375719408495000000000090`:
  + Identificador da transação: `1126253375719408495`
  + Identificador de comando: `112625337571940849500000000009` indica o nono comando no bloco de transação
  + Identificador do tipo de nó: `0` indica um nó participante

## Usar o rastreamento de consultas
<a name="limitless-query.tracing.using"></a>

Execute as seguintes tarefas para usar o rastreamento de consultas:

1. Verifique se o rastreamento está habilitado.

   Você pode verificar o seguinte comando:

   ```
   SHOW rds_aurora.limitless_log_distributed_trace_id;
   ```

   Por padrão, ele é habilitado (`on`). Se não estiver habilitado, configure-o usando este comando:

   ```
   SET rds_aurora.limitless_log_distributed_trace_id = on;
   ```

1. Controle o volume dos logs impressos configurando o nível de severidade do log.

   O volume de log é controlado pelo parâmetro `log_min_messages`. O parâmetro `log_min_error_statement` é usado para imprimir a linha `STATEMENT` com o ID de rastreamento. Por padrão, ambos estão definidos como `ERROR`. Você pode verificar usando os seguintes comandos:

   ```
   SHOW log_min_messages;
   SHOW log_min_error_statement;
   ```

   Para atualizar o nível de gravidade e imprimir a linha `STATEMENT` da sessão atual, use os seguintes comandos com um desses níveis de gravidade:

   ```
   SET log_min_messages = '{{DEBUG5}} | {{DEBUG4}} | {{DEBUG3}} | {{DEBUG2}} | {{DEBUG1}} | {{INFO}} | {{NOTICE}} | {{WARNING}} | {{ERROR}} | {{LOG}} | {{FATAL}} | {{PANIC}}';
   SET log_min_error_statement = '{{DEBUG5}} | {{DEBUG4}} | {{DEBUG3}} | {{DEBUG2}} | {{DEBUG1}} | {{INFO}} | {{NOTICE}} | {{WARNING}} | {{ERROR}} | {{LOG}} | {{FATAL}} | {{PANIC}}';
   ```

   Por exemplo:

   ```
   SET log_min_messages = 'WARNING';
   SET log_min_error_statement = 'WARNING';
   ```

1. Habilite a impressão do ID de rastreamento nos logs acima de um tempo de execução específico.

   O parâmetro `log_min_duration_statement` pode ser alterado para o tempo mínimo de execução da consulta acima do qual a consulta imprime uma linha de log com a duração da execução, junto com os IDs de rastreamento em todo o cluster de banco de dados. Por padrão, esse parâmetro é definido como `-1`, o que significa que está desabilitado. Você pode verificar o seguinte comando:

   ```
   SHOW log_min_duration_statement;
   ```

   Alterá-lo para `0` imprime a duração e o ID de rastreamento nos logs de cada consulta no cluster de banco de dados. É possível defini-lo como `0` para a sessão atual usando o seguinte comando:

   ```
   SET log_min_duration_statement = 0;
   ```

1. Obtenha o ID de rastreamento.

   Depois de executar uma consulta (mesmo dentro de um bloco de transação explícito), chame a função `rds_aurora.limitless_get_last_trace_id` para obter o ID de rastreamento da última consulta executada:

   ```
   SELECT * FROM rds_aurora.limitless_get_last_trace_id();
   ```

   Essa função retorna o identificador da transação e o identificador do comando. Ela não retorna o identificador do tipo de nó.

   ```
   => SELECT * FROM customers;
    customer_id | fname | lname 
   -------------+-------+-------
   (0 rows)
   
   => SELECT * FROM rds_aurora.limitless_get_last_trace_id();
    transaction_identifier |       command_identifier       
   ------------------------+--------------------------------
    10104661421959001813   | 101046614219590018130000000001
   (1 row)
   ```

   A função retorna uma linha em branco para consultas não distribuídas, pois elas não têm um ID de rastreamento.

   ```
   => SET search_path = public;
   SET
   
   => SELECT * FROM rds_aurora.limitless_get_last_trace_id();
    transaction_identifier | command_identifier 
   ------------------------+--------------------
                           | 
   (1 row)
   ```
**nota**  
Para consultas VACUUM e ANALYZE, a instrução de duração não é registrada com o ID de rastreamento. Portanto, `limitless_get_last_trace_id()` não retorna o ID de rastreamento. Se VACUUM ou ANALYZE for uma operação de longa duração, você pode usar a seguinte consulta para obter o ID de rastreamento dessa operação:  

   ```
   SELECT * FROM rds_aurora.limitless_stat_activity 
   WHERE distributed_tracing_id IS NOT NULL;
   ```
Se o servidor for interrompido antes de você encontrar o último ID de rastreamento, será necessário pesquisar os logs do PostgreSQL manualmente para encontrar os IDs de rastreamento nos logs logo antes da falha.

1. Pesquise o ID de rastreamento nos logs do cluster de banco de dados usando o CloudWatch.

   Use o [CloudWatch Insights](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AnalyzingLogData.html) para consultar o grupo de logs do cluster de banco de dados, conforme mostrado nos exemplos a seguir.
   + Consultar um identificador de transação específico e todos os comandos executados dentro dele:

     ```
     fields @timestamp, @message
     | filter @message like /10104661421959001813/
     | sort @timestamp desc
     ```
   + Consultar um identificador de comando específico:

     ```
     fields @timestamp, @message
     | filter @message like /101046614219590018130000000001/
     | sort @timestamp desc
     ```

1. Examine todos os logs em todo o cluster de banco de dados produzidos pela consulta distribuída.

## Exemplos de log
<a name="limitless-query.tracing.examples"></a>

Os exemplos a seguir mostram o uso do rastreamento de consultas.

### Correlacionar logs para consultas propensas a erros
<a name="limitless-query.tracing.example1"></a>

Neste exemplo, o comando `TRUNCATE` é executado na tabela `customers` quando essa tabela não existe.

**Sem rastreamento de consultas**  
Arquivo de log do PostgreSQL no roteador coordenador:  

```
2023-09-26 04:03:19 UTC:[local]: postgres@postgres_limitless:[27503]:ERROR: failed to execute remote query
2023-09-26 04:03:19 UTC:[local]: postgres@postgres_limitless:[27503]:DETAIL: relation "public.customers" does not exist
2023-09-26 04:03:19 UTC:[local]: postgres@postgres_limitless:[27503]:CONTEXT: remote SQL command: truncate public.customers;
2023-09-26 04:03:19 UTC:[local]: postgres@postgres_limitless:[27503]:STATEMENT: truncate customers;
```
Arquivo de log do PostgreSQL em um fragmento participante:  

```
2023-09-26 04:03:19 UTC:[local]: postgres@postgres_limitless:[ 27503]:ERROR: failed to execute remote query
2023-09-26 04:03:19 UTC:[local]: postgres@postgres_limitless:[ 27503]:STATEMENT: truncate customers;
```
Esses logs são comuns. Eles não têm os identificadores precisos necessários para correlacionar facilmente as consultas em todo o cluster de banco de dados.

**Com rastreamento de consultas**  
Arquivo de log do PostgreSQL no roteador coordenador:  

```
2023-09-26 04:03:19 UTC:[local]:postgres@postgres_limitless:[27503]:ERROR: failed to execute remote query
2023-09-26 04:03:19 UTC:[local]:postgres@postgres_limitless:[27503]:DETAIL: relation "public.customers" does not exist
2023-09-26 04:03:19 UTC:[local]:postgres@postgres_limitless:[27503]:CONTEXT: remote SQL command: truncate public.customers;
2023-09-26 04:03:19 UTC:[local]:postgres@postgres_limitless:[27503]:STATEMENT: /* tid = 1126253375719408502700000000011 */ truncate customers;
```
Arquivo de log do PostgreSQL em um fragmento participante:  

```
2023-09-26 04:03:19 UTC:[local]:postgres@postgres_limitless:[27503]:ERROR:  failed to execute remote query
2023-09-26 04:03:19 UTC:[local]:postgres@postgres_limitless:[27503]:STATEMENT:  /* tid = 1126253375719408502700000000010 */ truncate customers;
```
Na presença do rastreamento de consulta, cada linha de log é anexada com um identificador único de 31 dígitos. Aqui, `1126253375719408502700000000011` e `1126253375719408502700000000010` representam os IDs de rastreamento para os nós coordenador e participante, respectivamente.  
+ Identificador da transação: `11262533757194085027`
+ Identificador de comando: `112625337571940850270000000001`
+ Identificador do tipo de nó: o último dígito, `1` ou `0`, indica um roteador coordenador e um nó participante, respectivamente.

### Correlacionar logs para encontrar o tempo de execução da consulta em vários nós
<a name="limitless-query.tracing.example2"></a>

Neste exemplo, o parâmetro `log_min_duration_statement` foi atualizado para `0` para imprimir a duração de todas as consultas.

**Sem rastreamento de consultas**  

```
2024-01-15 07:28:46 UTC:[local]:postgres@postgres_limitless:[178322]:LOG: duration: 12.779 ms statement: select * from customers;
```

**Com rastreamento de consultas**  
Arquivo de log do PostgreSQL no roteador coordenador:  

```
2024-01-15 07:32:08 UTC:[local]:postgres@postgres_limitless:[183877]:LOG: duration: 12.618 ms statement: /* tid = 0457669566240497088400000000011 */ select * from customers;
```
Arquivo de log do PostgreSQL em um fragmento participante:  

```
2024-01-15 07:32:08 UTC:localhost(46358):postgres@postgres_limitless:[183944]:LOG: duration: 0.279 ms statement: /* tid = 0457669566240497088400000000010 */ START TRANSACTION ISOLATION LEVEL READ COMMITTED
2024-01-15 07:32:08 UTC:localhost(46358):postgres@postgres_limitless:[183944]:LOG: duration: 0.249 ms parse <unnamed>: SELECT customer_id, fname, lname FROM public.customers
2024-01-15 07:32:08 UTC:localhost(46358):postgres@postgres_limitless:[183944]:LOG: duration: 0.398 ms bind <unnamed>/c1: SELECT customer_id, fname, lname FROM public.customers
2024-01-15 07:32:08 UTC:localhost(46358):postgres@postgres_limitless:[183944]:LOG: duration: 0.019 ms execute <unnamed>/c1: SELECT customer_id, fname, lname FROM public.customers
2024-01-15 07:32:08 UTC:localhost(46358):postgres@postgres_limitless:[183944]:LOG: duration: 0.073 ms statement: /* tid = 0457669566240497088400000000010 */ COMMIT TRANSACTION
```