Estatísticas das consultas ativas mais antigas

As consultas ativas mais antigas, também conhecidas como consultas de execução mais longa, são uma lista de consultas ativas na sua base de dados, ordenadas pela duração da execução. A obtenção de estatísticas sobre estas consultas pode ajudar a identificar as causas da latência do sistema e da utilização elevada da CPU à medida que ocorrem.

O Spanner fornece uma tabela incorporada,SPANNER_SYS.OLDEST_ACTIVE_QUERIES, que apresenta as consultas em execução, incluindo consultas que contêm declarações DML, ordenadas por hora de início, por ordem ascendente. Não inclui consultas de streams de alterações.

Se existirem muitas consultas em execução, os resultados podem ser limitados a um subconjunto do total de consultas devido às restrições de memória que o sistema aplica à recolha destes dados. Por conseguinte, o Spanner fornece uma tabela adicional, SPANNER_SYS.ACTIVE_QUERIES_SUMMARY, que mostra estatísticas de resumo para todas as consultas ativas (exceto para consultas de streams de alterações). Pode obter informações de ambas as tabelas incorporadas através de declarações SQL.

Neste documento, vamos descrever ambas as tabelas, mostrar alguns exemplos de consultas que usam estas tabelas e, por último, demonstrar como as usar para ajudar a mitigar problemas causados por consultas ativas.

Aceda às estatísticas das consultas ativas mais antigas

Os dados de SPANNER_SYS só estão disponíveis através de interfaces SQL; por exemplo:

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

  • Executar uma leitura forte a partir de uma única linha ou de várias linhas numa tabela.
  • Executar uma leitura desatualizada de uma única linha ou várias linhas numa tabela.
  • Ler a partir de uma única linha ou de várias linhas num índice secundário.

Estatísticas de OLDEST_ACTIVE_QUERIES

SPANNER_SYS.OLDEST_ACTIVE_QUERIES devolve uma lista de consultas ativas ordenadas por hora de início. Se existirem muitas consultas em execução, os resultados podem estar limitados a um subconjunto do total de consultas devido às restrições de memória que o Spanner aplica à recolha destes dados. Para ver estatísticas de resumo de todas as consultas ativas, consulte ACTIVE_QUERIES_SUMMARY.

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

Nome da coluna Tipo Descrição
START_TIME TIMESTAMP Hora de início da consulta.
TEXT_FINGERPRINT INT64 A impressão digital é um hash da etiqueta de pedido ou, se não estiver presente uma etiqueta, 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 for truncado, este valor é TRUE. Se o texto da consulta não for truncado, este valor é FALSE.
SESSION_ID STRING O ID da sessão que está a executar a consulta.
QUERY_ID STRING O ID da consulta. Pode usar este 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. Por vezes, o endereço IP do cliente pode ser ocultado. O endereço IP apresentado aqui é consistente com os registos de auditoria e segue as mesmas diretrizes de ocultação. Para mais informações, consulte Endereço IP do autor da chamada nos registos de auditoria. Recomendamos que solicite o endereço IP do cliente apenas quando for necessário, uma vez que os pedidos de endereços IP do cliente podem incorrer em latência adicional.
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 onde o servidor raiz do Spanner processa a consulta. Para mais informações, consulte o artigo Ciclo de vida de uma consulta.
PRIORITY STRING A prioridade da consulta. Para ver 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.

Consultas de exemplo

Pode executar as seguintes declarações SQL de exemplo através das bibliotecas de cliente, da CLI do Google Cloud ou da Google Cloud consola.

Liste as consultas ativas em execução mais antigas

A consulta seguinte devolve uma lista das consultas em execução mais antigas, ordenadas pela hora 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;
Resultado da consulta

A tabela seguinte mostra o resultado da execução da consulta mencionada anteriormente:

start_time text_fingerprint texto 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; FALSE 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; FALSE 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; FALSE 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

Apresentar as 2 consultas em execução mais antigas

Este exemplo, que é uma ligeira variação da consulta anterior, devolve as 2 consultas em execução mais antigas ordenadas pela hora 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;
Resultado da consulta

A tabela seguinte mostra o resultado da execução da consulta mencionada anteriormente:

start_time text_fingerprint texto 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 estatísticas de resumo para todas as consultas ativas. As consultas são agrupadas nos seguintes conjuntos:

  • com mais de 1 segundo
  • Mais antiga do que 10 segundos
  • Mais antiga do que 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 para a hora 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.

Uma consulta pode ser contabilizada em mais do que um destes grupos. Por exemplo, se uma consulta tiver sido executada durante 12 segundos, é contabilizada em COUNT_OLDER_THAN_1S e COUNT_OLDER_THAN_10S porque cumpre ambos os critérios.

Consultas de exemplo

Pode executar as seguintes declarações SQL de exemplo através das bibliotecas de cliente, do gcloud spanner ou da Google Cloud consola.

Obtenha um resumo das consultas ativas

A consulta seguinte devolve as estatísticas de resumo sobre as consultas em execução.

SELECT active_count,
       oldest_start_time,
       count_older_than_1s,
       count_older_than_10s,
       count_older_than_100s
FROM spanner_sys.active_queries_summary;
Resultado 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 oferecer-lhe as estatísticas mais abrangentes possíveis, existem algumas circunstâncias em que as consultas não são incluídas nos dados devolvidos nestas tabelas.

  • As consultas DML (UPDATE, INSERT, DELETE) não estão incluídas se estiverem na fase Aplicar mutações.

  • Uma consulta não é incluída se estiver a meio do reinício devido a um erro temporário.

  • As consultas de servidores sobrecarregados ou sem resposta não estão incluídas.

  • Não é possível ler nem consultar a tabela OLDEST_ACTIVE_QUERIES numa transação de leitura/escrita. Mesmo numa transação só de leitura, ignora a indicação de tempo da transação e devolve sempre os dados atuais a partir da respetiva execução. Em casos raros, pode devolver um erro ABORTED com resultados parciais. Nesse caso, rejeite os resultados parciais e tente a consulta novamente.

  • Se a coluna CLIENT_IP_ADDRESS devolver uma string <error>, indica um problema transitório que não deve afetar o resto da consulta. Tente novamente a consulta para obter o endereço IP do cliente.

Use dados de consultas ativas para resolver problemas de elevada utilização da CPU

As estatísticas de consultas e as estatísticas de transações fornecem informações úteis quando resolve problemas de latência numa base de dados do Spanner. Estas ferramentas fornecem informações sobre as consultas que já foram concluídas. No entanto, por vezes, é necessário saber o que está a ser executado no sistema. Por exemplo, considere o cenário em que a utilização da CPU é bastante elevada e quer responder às seguintes perguntas.

  • Quantas consultas estão a ser executadas neste momento?
  • O que são estas consultas?
  • Quantas consultas estão a ser executadas durante muito tempo, ou seja, mais de 100 segundos?
  • Que sessão está a executar a consulta?

Com as respostas às perguntas anteriores, pode decidir tomar a seguinte ação.

  • Eliminar a sessão que executa a consulta para uma resolução imediata.
  • Melhore o desempenho das consultas adicionando um índice.
  • Reduza a frequência da consulta se estiver associada a uma tarefa em segundo plano periódica.
  • Identificar o utilizador ou o componente que está a emitir a consulta e que pode não estar autorizado a executá-la.

Neste passo a passo, examinamos as nossas consultas ativas e determinamos que ação, se aplicável, tomar.

Obtenha um resumo das consultas ativas

No nosso cenário de exemplo, verificamos uma utilização da CPU superior ao normal, pelo que decidimos executar a seguinte consulta para devolver 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 gera os seguintes resultados.

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

Descobrimos que temos uma consulta em execução há mais de 100 segundos. Isto é invulgar para a nossa base de dados, por isso, queremos investigar mais aprofundadamente.

Obtenha uma lista de consultas ativas

Determinámos no passo anterior que temos uma consulta em execução há mais de 100 segundos.Para investigar mais a fundo, executamos a seguinte consulta para devolver mais informações sobre as 5 consultas em execução mais antigas.

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, executámos a consulta a 28 de março de 2024, aproximadamente às 16:44:09 EDT, e foram devolvidos os seguintes resultados. (Pode ter de deslocar a página horizontalmente para ver o resultado completo.)

start_time text_fingerprint texto 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) está realçada na tabela. É um CROSS JOIN caro. Decidimos tomar medidas.

Cancele uma consulta dispendiosa

Neste exemplo, encontrámos uma consulta que estava a executar uma CROSS JOIN dispendiosa, pelo que decidimos cancelá-la. Os resultados da consulta que recebemos no passo anterior incluíram um query_id. Podemos executar o seguinte comando CALL cancel_query(query_id) para o GoogleSQL e o comando spanner.cancel_query(query_id) para o PostgreSQL para cancelar a consulta.

GoogleSQL

CALL cancel_query(query_id)

PostgreSQL

CALL spanner.cancel_query(query_id)

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

CALL cancel_query('37190103859320827')

Tem de consultar a spanner_sys.oldest_active_queriestabela para verificar se a consulta foi cancelada.

Este passo a passo demonstra como usar SPANNER_SYS.OLDEST_ACTIVE_QUERIES e SPANNER_SYS.ACTIVE_QUERIES_SUMMARY para analisar as nossas consultas em execução e tomar medidas, se necessário, em quaisquer consultas que estejam a contribuir para uma elevada utilização da CPU. Claro que é sempre mais barato evitar operações dispendiosas e criar o esquema certo para os seus exemplos de utilização. Para mais informações sobre a criação de declarações SQL executadas de forma eficiente, consulte as práticas recomendadas de SQL.

O que se segue?