Estatísticas das consultas ativas mais antigas

Consultas ativas mais antigas, também conhecidas como consultas mais longas, é uma lista das consultas ativas no seu banco de dados, classificadas pelo tempo em que estavam em execução. Conseguir informações sobre essas consultas pode ajudar a identificar as causas de latência do sistema e do alto uso da CPU conforme elas acontecem.

O Spanner fornece uma tabela integrada,SPANNER_SYS.OLDEST_ACTIVE_QUERIES, que lista as consultas em execução, incluindo aquelas que contêm instruções DML, classificadas pelo horário de início, em ordem crescente. Ela não inclui consultas de fluxo de alterações.

Se houver muitas consultas em execução, os resultados poderão ser limitados a um subconjunto do total de consultas devido às restrições de memória que o sistema impõe na coleta desses dados. Portanto, o Spanner fornece uma tabela adicional, SPANNER_SYS.ACTIVE_QUERIES_SUMMARY, que mostra estatísticas resumidas de todas as consultas ativas, exceto as de fluxo de alterações. É possível recuperar informações dessas duas tabelas integradas usando instruções SQL.

Neste documento, descreveremos as duas tabelas, mostraremos alguns exemplos de consulta que usam essas tabelas e, finalmente, demonstraremos como usá-las para ajudar a mitigar problemas causados por consultas ativas.

Acessar as estatísticas das consultas ativas mais antigas

Os dados de SPANNER_SYS estão disponíveis somente por interfaces SQL. Por exemplo:

O Spanner não é compatível com SPANNER_SYS com os seguintes métodos de leitura única:

  • realizar uma leitura forte de uma única linha ou de várias linhas em uma tabela;
  • realizar uma leitura desatualizada de uma única linha ou várias linhas em uma tabela;
  • ler uma única linha ou várias linhas em um índice secundário.

Estatísticas de OLDEST_ACTIVE_QUERIES

SPANNER_SYS.OLDEST_ACTIVE_QUERIES retorna uma lista de consultas ativas classificadas pelo horário de início. Se houver muitas consultas em execução, os resultados poderão ser limitados a um subconjunto do total de consultas devido às restrições de memória que o Spanner impõe na coleta desses dados. Para ver as estatísticas resumidas de todas as consultas ativas, consulte ACTIVE_QUERIES_SUMMARY.

Esquema para todas as tabelas de estatísticas de consultas ativas mais antigas

Nome da coluna Tipo Descrição
START_TIME TIMESTAMP Horário de início da consulta.
TEXT_FINGERPRINT INT64 A impressão digital é um hash da tag de solicitação ou, se uma tag não estiver presente, um hash do texto da consulta.
TEXT STRING O texto da instrução de consulta.
TEXT_TRUNCATED BOOL Se o texto da consulta no campo TEXT estiver truncado, esse valor será TRUE. Se o texto da consulta não for truncado, esse valor será FALSE.
SESSION_ID STRING O ID da sessão que está executando a consulta.
QUERY_ID STRING O ID da consulta. Você pode usar esse ID com CALL cancel_query(query_id) para cancelar a consulta.
CLIENT_IP_ADDRESS STRING O endereço IP do cliente que solicitou a consulta. Às vezes, o endereço IP do cliente pode ser editado. O endereço IP mostrado aqui é consistente com os registros de auditoria e segue as mesmas diretrizes de redação. Para mais informações, consulte Endereço IP do autor da chamada em registros de auditoria. Recomendamos solicitar o endereço IP do cliente apenas quando ele for necessário, já que as solicitações podem gerar mais latência.
API_CLIENT_HEADER STRING O cabeçalho api_client do cliente.
USER_AGENT_HEADER STRING O cabeçalho user_agent que o Spanner recebeu do cliente.
SERVER_REGION STRING A região em que o servidor raiz do Spanner processa a consulta. Para mais informações, consulte Ciclo de vida de uma consulta.
PRIORITY STRING A prioridade da consulta. Para conferir as prioridades disponíveis, consulte RequestOptions.
TRANSACTION_TYPE STRING O tipo de transação da consulta. Os valores possíveis são READ_ONLY, READ_WRITE e NONE.

Exemplo de consultas

É possível executar as seguintes instruções SQL usando as bibliotecas de cliente, a Google Cloud CLI ou o console do Google Cloud .

Listar as consultas ativas em execução mais antigas

A consulta a seguir retorna uma lista de consultas em execução mais antigas, classificadas pelo horário de início da consulta.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id,
       query_id,
       api_client_header,
       server_region,
       priority,
       transaction_type
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC;
Saída da consulta

A tabela a seguir mostra a saída da execução da consulta mencionada anteriormente:

start_time text_fingerprint text text_truncated session_id query_id api_client_header server_region prioridade transaction_type
2025-05-20T03:29:54.287255Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId as b_id, b.AlbumId as b_albumid, b.TrackId as b_trackId FROM Songs as a CROSS JOIN Songs as b; FALSO AG46FS6K3adF 9023439241169932454 gl-go/1.25.0-20250216-RC00 gccl/1.73.0 gapic/1.73.0 gax/2.14.1 grpc/1.69.2 us-central1 PRIORITY_HIGH READ_ONLY
2025-05-20T03:31:52.40808Z 1688332608621812214 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; FALSO AG46FS6paJPKDOb 2729381896189388167 gl-go/1.25.0-20250216-RC00 gccl/1.73.0 gapic/1.73.0 gax/2.14.1 grpc/1.69.2 us-central1 PRIORITY_HIGH READ_WRITE
2025-05-20T03:31:52.591212Z 6561582859583559006 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE a.SingerId > 10 LIMIT 1000000; FALSO AG46FS7Pb_9H6J6p 9125776389780080794 gl-go/1.25.0-20250216-RC00 gccl/1.73.0 gapic/1.73.0 gax/2.14.1 grpc/1.69.2 us-central1 PRIORITY_LOW READ_ONLY

Como listar as duas consultas em execução mais antigas

Uma pequena variação na consulta anterior, este exemplo retorna as duas consultas em execução mais antigas classificadas pelo horário de início da consulta.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 2;
Saída da consulta

A tabela a seguir mostra a saída da execução da consulta mencionada anteriormente:

start_time text_fingerprint text text_truncated session_id
2039-07-18T07:52:28.225877Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId as b_id, b.AlbumId as b_albumid, b.TrackId as b_trackId FROM Songs as a CROSS JOIN Songs as b; Falso ACjbPvYsuRt
2039-07-18T07:54:08.622081Z -9206690983832919848 SELECT a.SingerId, a.AlbumId, a.TrackId, a.SongName, s.FirstName, s.LastName FROM Songs as a JOIN Singers as s ON s.SingerId = a.SingerId WHERE STARTS_WITH(s.FirstName, 'FirstName') LIMIT 1000000; Falso ACjbPvaF3yK

ACTIVE_QUERIES_SUMMARY

A tabela de estatísticas SPANNER_SYS.ACTIVE_QUERIES_SUMMARY mostra um resumo de todas as consultas ativas. As consultas são agrupadas nos seguintes intervalos:

  • com mais de 1 segundo
  • com mais de 10 segundos
  • com mais de 100 segundos

Esquema da tabela para ACTIVE_QUERIES_SUMMARY

Nome da coluna Tipo Descrição
ACTIVE_COUNT INT64 O número total de consultas em execução.
OLDEST_START_TIME TIMESTAMP Um limite superior no horário de início da consulta em execução mais antiga.
COUNT_OLDER_THAN_1S INT64 O número de consultas com mais de 1 segundo.
COUNT_OLDER_THAN_10S INT64 O número de consultas com mais de 10 segundos
COUNT_OLDER_THAN_100S INT64 O número de consultas com mais de 100 segundos

É possível contar uma consulta em mais de um desses buckets. Por exemplo, se uma consulta estiver em execução por 12 segundos, ela será contada em COUNT_OLDER_THAN_1S e COUNT_OLDER_THAN_10S porque atende aos dois critérios.

Exemplo de consultas

É possível executar as seguintes instruções SQL de exemplo usando as bibliotecas de cliente, o gcloud spanner ou o console doGoogle Cloud .

Recuperar um resumo das consultas ativas

A consulta a seguir retorna as estatísticas resumidas da execução de consultas.

SELECT active_count,
       oldest_start_time,
       count_older_than_1s,
       count_older_than_10s,
       count_older_than_100s
FROM spanner_sys.active_queries_summary;
Saída da consulta
active_count oldest_start_time count_older_than_1s count_older_than_10s count_older_than_100s
22 2039-07-18T07:52:28.225877Z 21 21 1

Limitações

Embora o objetivo seja fornecer os insights mais abrangentes possíveis, há algumas circunstâncias em que as consultas não estão incluídas nos dados retornados nessas tabelas.

  • As consultas DML (UPDATE, INSERT, DELETE) não são incluídas se estiverem na fase Apply mutations.

  • Uma consulta não será incluída se estiver no meio da reinicialização devido a um erro transitório.

  • As consultas de servidores sobrecarregados ou que não respondem não são incluídas.

  • Não é possível ler ou consultar a tabela OLDEST_ACTIVE_QUERIES em uma transação de leitura e gravação. Mesmo em uma transação somente leitura, ele ignora o carimbo de data/hora da transação e sempre retorna dados atuais a partir da execução. Em casos raros, ele pode retornar um erro ABORTED com resultados parciais. Nesse caso, descarte os resultados parciais e tente a consulta novamente.

  • Se a coluna CLIENT_IP_ADDRESS retornar uma string <error>, isso indica um problema temporário que não deve afetar o restante da consulta. Repita a consulta para recuperar o endereço IP do cliente.

Usar dados de consultas ativas para resolver problemas de alta utilização da CPU

As estatísticas de consulta e as estatísticas de transação fornecem informações úteis ao solucionar problemas de latência em um banco de dados do Spanner. Essas ferramentas fornecem informações sobre as consultas que já foram concluídas. No entanto, às vezes é necessário saber o que está sendo executado no sistema. Por exemplo, considere o cenário quando a utilização da CPU for muito alta e você quiser responder às perguntas a seguir.

  • Quantas consultas estão em execução no momento?
  • O que são essas consultas?
  • Quantas consultas estão em execução por um longo período, ou seja, mais de 100 segundos?
  • Qual sessão está executando a consulta?

Com respostas às perguntas anteriores, você pode optar pela ação a seguir.

  • Exclua a sessão que executa a consulta para uma resolução imediata.
  • Melhore o desempenho da consulta adicionando um índice.
  • Reduza a frequência da consulta, se ela estiver associada a uma tarefa periódica em segundo plano.
  • Identifique o usuário ou componente que emite a consulta e que pode não estar autorizado a executar a consulta.

Neste tutorial, examinaremos nossas consultas ativas e determinaremos qual ação tomar, se houver.

Recuperar um resumo das consultas ativas

No nosso cenário de exemplo, notamos um uso maior do que o uso normal da CPU. Por isso, decidimos executar a consulta a seguir para retornar um resumo das consultas ativas.

SELECT active_count,
       oldest_start_time,
       count_older_than_1s,
       count_older_than_10s,
       count_older_than_100s
FROM spanner_sys.active_queries_summary;

A consulta apresenta os resultados a seguir.

active_count oldest_start_time count_older_than_1s count_older_than_10s count_older_than_100s
22 2039-07-18T07:52:28.225877Z 21 21 1

No momento, temos uma consulta em execução por mais de 100 segundos. Isso é incomum para nosso banco de dados, então queremos investigar mais a fundo.

Recuperar uma lista de consultas ativas

Decidimos na etapa anterior que temos uma consulta em execução por mais de 100 segundos. Para investigar mais a fundo, executamos a seguinte consulta para retornar mais informações sobre as cinco principais consultas em execução.

SELECT start_time,
       text_fingerprint,
       text,
       text_truncated,
       session_id,
       query_id
FROM spanner_sys.oldest_active_queries
ORDER BY start_time ASC LIMIT 5;

Neste exemplo, executamos a consulta em 28 de março de 2024, aproximadamente às 16h44:09 EDT, e ela retornou os seguintes resultados. Talvez seja necessário rolar a tela horizontalmente para visualizar toda a saída.

start_time text_fingerprint text text_truncated session_id query_id
2024-03-28 16:44:09.356939+00:00 -2833175298673875968 select * from spanner_sys.oldest_active_queries falso ACjbPvYsucrtcffHrRK6aObeIjZf12tSUwOsim-g1WC3IhqF4epzICCQR3GCHw 37190103859320827
2039-07-18T07:52:28.225877Z -3426560921851907385 SELECT a.SingerId, a.AlbumId, a.TrackId, b.SingerId as b_id, b.AlbumId as b_albumid, b.TrackId as b_trackId FROM Songs as a CROSS JOIN Songs as b; falso ACjbPvaF3yKiNfxXFod2LPoFaXjKR759Bw1o34206vv0t7eOrD3wxZhu8U6ohQ 48946620525959556

A consulta mais antiga (impressão digital = -2833175298673875968) é destacada na tabela. É um CROSS JOIN caro. Decidimos tomar medidas.

Cancelar uma consulta cara

Neste exemplo, encontramos uma consulta que estava executando um CROSS JOIN caro, por isso decidimos cancelar a consulta. Os resultados da consulta que recebemos na etapa anterior incluíam um query_id. Podemos executar o seguinte comando CALL cancel_query(query_id) para GoogleSQL e o comando spanner.cancel_query(query_id) para PostgreSQL para cancelar a consulta.

GoogleSQL

CALL cancel_query(query_id)

PostgreSQL

CALL spanner.cancel_query(query_id)

Por exemplo, na instrução a seguir, CALL cancela uma consulta com o ID 37190103859320827:

CALL cancel_query('37190103859320827')

É necessário consultar a tabela spanner_sys.oldest_active_queries para verificar se a consulta foi cancelada.

Este tutorial demonstra como usar SPANNER_SYS.OLDEST_ACTIVE_QUERIES e SPANNER_SYS.ACTIVE_QUERIES_SUMMARY para analisar nossas consultas em execução e agir, se necessário, em todas as consultas que contribuem para o alto uso da CPU. Obviamente, é sempre mais barato evitar operações caras e desenvolver o esquema certo para seus casos de uso. Para mais informações sobre como construir instruções SQL que são executadas com eficiência, consulte Práticas recomendadas de SQL.

A seguir