Estatísticas de transações

O Spanner fornece tabelas incorporadas que armazenam estatísticas sobre transações. Pode obter estatísticas destas tabelas SPANNER_SYS.TXN_STATS* através de declarações SQL.

Quando usar estatísticas de transações

As estatísticas de transações são úteis quando investiga problemas de desempenho. Por exemplo, pode verificar se existem transações de execução lenta que possam estar a afetar o desempenho ou as consultas por segundo (QPS) na sua base de dados. Outro cenário é quando as suas aplicações cliente estão a sofrer uma latência de execução de transações elevada. A análise das estatísticas de transações pode ajudar a descobrir potenciais gargalos, como grandes volumes de atualizações a uma coluna específica, que podem estar a afetar a latência.

Aceda às estatísticas de transações

O Spanner fornece as estatísticas de transações de tabelas no esquema SPANNER_SYS. Pode usar as seguintes formas para aceder aos dados do SPANNER_SYS:

Os seguintes métodos de leitura única fornecidos pelo Spanner não suportam o SPANNER_SYS:

  • 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.
  • Leitura de uma única linha ou várias linhas num índice secundário.

Estatísticas de latência agrupadas por transação

As tabelas seguintes monitorizam as estatísticas das transações que consomem recursos durante um período específico.TOP

  • SPANNER_SYS.TXN_STATS_TOP_MINUTE: estatísticas de transações agregadas em intervalos de 1 minuto.

  • SPANNER_SYS.TXN_STATS_TOP_10MINUTE: estatísticas de transações agregadas em intervalos de 10 minutos.

  • SPANNER_SYS.TXN_STATS_TOP_HOUR: estatísticas de transações agregadas em intervalos de 1 hora.

Estas tabelas têm as seguintes propriedades:

  • Cada tabela contém dados para intervalos de tempo não sobrepostos com a duração especificada no nome da tabela.

  • Os intervalos baseiam-se nas horas do relógio. Os intervalos de 1 minuto terminam no minuto, os intervalos de 10 minutos terminam a cada 10 minutos a partir da hora, e os intervalos de 1 hora terminam na hora.

    Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para consultas SQL são:

    • 1 minuto: 11:58:00–11:58:59
    • 10 minutos: 11:40:00–11:49:59
    • 1 hora: 10:00:00–10:59:59
  • O Spanner agrupa as estatísticas por FPRINT (impressão digital) das transações. Se estiver presente uma etiqueta de transação, FPRINT é o hash da etiqueta. Caso contrário, é o hash calculado com base nas operações envolvidas na transação.

  • Uma vez que as estatísticas são agrupadas com base em FPRINT, se a mesma transação for executada várias vezes num intervalo de tempo, continuamos a ver apenas uma entrada para essa transação nestas tabelas.

  • Cada linha contém estatísticas para todas as execuções de uma determinada transação para a qual o Spanner captura estatísticas durante o intervalo especificado.

  • Se o Spanner não conseguir armazenar estatísticas para todas as transações executadas durante o intervalo nestas tabelas, o sistema dá prioridade às transações com a latência, as tentativas de confirmação e os bytes escritos mais elevados durante o intervalo especificado.

  • Todas as colunas nas tabelas são anuláveis.

Esquema da tabela

Nome da coluna Tipo Descrição
INTERVAL_END TIMESTAMP Fim do intervalo de tempo em que ocorreram as execuções de transações incluídas.
TRANSACTION_TAG STRING A etiqueta de transação opcional para esta operação de transação. Para mais informações sobre a utilização de etiquetas, consulte o artigo Resolução de problemas com etiquetas de transações. As estatísticas de várias transações que têm a mesma string de etiqueta são agrupadas numa única linha com a `TRANSACTION_TAG` correspondente a essa string de etiqueta.
FPRINT INT64 O hash de TRANSACTION_TAG, se estiver presente; caso contrário, o hash é calculado com base nas operações envolvidas na transação. INTERVAL_END e FPRINT atuam em conjunto como uma chave única para estas tabelas.
READ_COLUMNS ARRAY<STRING> O conjunto de colunas lidas pela transação.
WRITE_CONSTRUCTIVE_COLUMNS ARRAY<STRING> O conjunto de colunas que foram escritas de forma construtiva (ou seja, atribuídas a novos valores) pela transação.

Para streams de alterações, se a transação envolver escritas em colunas e tabelas monitorizadas por uma stream de alterações, WRITE_CONSTRUCTIVE_COLUMNS contém duas colunas: .data e ._exists 1, com o prefixo do nome de uma stream de alterações.
WRITE_DELETE_TABLES ARRAY<STRING> O conjunto de tabelas cujas linhas foram eliminadas ou substituídas pela transação.
ATTEMPT_COUNT INT64 O número total de vezes que a transação é tentada, incluindo as tentativas que são anuladas antes de chamar `commit`.
COMMIT_ATTEMPT_COUNT INT64 Número total de tentativas de confirmação de transações. Tem de corresponder ao número de chamadas para o método commit da transação.
COMMIT_ABORT_COUNT INT64 Número total de tentativas de transação que foram anuladas, incluindo as que foram anuladas antes de chamar o método commit da transação.
COMMIT_RETRY_COUNT INT64 O número total de tentativas que são novas tentativas de tentativas anteriormente anuladas. Uma transação do Spanner pode ser tentada várias vezes antes de ser confirmada devido a contestações de bloqueios ou eventos transitórios. Um número elevado de tentativas em relação às tentativas de confirmação indica que podem existir problemas que vale a pena investigar. Para mais informações, consulte a secção Compreender as transações e as quantidades de commits nesta página.
COMMIT_FAILED_PRECONDITION_COUNT INT64 O número total de tentativas de confirmação de transações que devolveram erros de pré-condição falhada, como violações de índice, a linha já existe, a linha não foi encontrada, etc.UNIQUE
SERIALIZABLE_PESSIMISTIC_TXN_COUNT INT64 Número total de tentativas de transação iniciadas com o nível de isolamento SERIALIZABLE e o bloqueio PESSIMISTIC. É um subconjunto de ATTEMPT_COUNT.
REPEATABLE_READ_OPTIMISTIC_TXN_COUNT INT64 Número total de tentativas de transação iniciadas com o nível de isolamento REPEATABLE READ e o bloqueio OPTIMISTIC. É um subconjunto de ATTEMPT_COUNT.
AVG_PARTICIPANTS FLOAT64 Número médio de participantes em cada tentativa de confirmação. Para saber mais acerca dos participantes, consulte Ciclo de vida das leituras e escritas do Spanner.
AVG_TOTAL_LATENCY_SECONDS FLOAT64 A média de segundos decorridos desde a primeira operação da transação até à confirmação/anulação.
AVG_COMMIT_LATENCY_SECONDS FLOAT64 Média de segundos necessários para realizar a operação de confirmação.
AVG_BYTES FLOAT64 Número médio de bytes escritos pela transação.
TOTAL_LATENCY_DISTRIBUTION ARRAY<STRUCT>

Um histograma da latência total de confirmação, que é o tempo desde a hora de início da primeira operação transacional até à hora de confirmação ou anulação, para todas as tentativas de uma transação.

Se uma transação for anulada várias vezes e, em seguida, for confirmada com êxito, a latência é medida para cada tentativa até à confirmação final bem-sucedida. Os valores são medidos em segundos.

A matriz contém um único elemento e tem o seguinte tipo:
ARRAY<STRUCT<
  COUNT INT64,
  MEAN FLOAT64,
  SUM_OF_SQUARED_DEVIATION FLOAT64,
  NUM_FINITE_BUCKETS INT64,
  GROWTH_FACTOR FLOAT64,
  SCALE FLOAT64,
  BUCKET_COUNTS ARRAY<INT64>>>

Para mais informações sobre os valores, consulte Distribuição.

Para calcular a latência do percentil desejado a partir da distribuição, use a SPANNER_SYS.DISTRIBUTION_PERCENTILE(distribution, n FLOAT64)função, que devolve o percentil n estimado. Para ver um exemplo relacionado, consulte o artigo Encontre a latência do percentil 99 para transações.

Para mais informações, consulte o artigo Percentis e métricas com valores de distribuição.

OPERATIONS_BY_TABLE ARRAY<STRUCT>

Impacto das operações INSERT ou UPDATE por transação, por tabela. Isto é indicado pelo número de vezes que as linhas são afetadas e o número de bytes escritos.

Esta coluna ajuda a visualizar a carga nas tabelas e fornece estatísticas sobre a taxa à qual uma transação escreve nas tabelas.

Especifique a matriz da seguinte forma:
ARRAY<STRUCT<
  TABLE STRING(MAX),
  INSERT_OR_UPDATE_COUNT INT64,
  INSERT_OR_UPDATE_BYTES INT64>>

1 _exists é um campo interno usado para verificar se existe ou não uma determinada linha.

Consultas de exemplo

Esta secção inclui vários exemplos de declarações SQL que obtêm estatísticas de transações. Pode executar estas declarações SQL através das bibliotecas de cliente, do gcloud spanner ou da Google Cloud consola.

Apresentar as estatísticas básicas de cada transação num determinado período

A consulta seguinte devolve os dados não processados das principais transações no minuto anterior.

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_total_latency_seconds,
       avg_commit_latency_seconds,
       operations_by_table,
       avg_bytes
FROM spanner_sys.txn_stats_top_minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_top_minute);
Resultado da consulta
fprint read_columns write_constructive_columns write_delete_tables avg_total_latency_seconds avg_commit_latency_seconds operations_by_table avg_bytes
40015598317 [] ["Routes.name", "Cars.model"] ["Users"] 0.006578737 0.006547737 [["Cars",1107,30996],["Routes",560,26880]] 25286
20524969030 ["id", "no"] [] [] 0.001732442 0.000247442 [] 0
77848338483 [] [] ["Cars", "Routes"] 0.033467418 0.000251418 [] 0

Apresente as transações com a latência de confirmação média mais elevada

A consulta seguinte devolve as transações com uma latência de confirmação média elevada na hora anterior, ordenadas da latência de confirmação média mais elevada para a mais baixa.

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_total_latency_seconds,
       avg_commit_latency_seconds,
       avg_bytes
FROM spanner_sys.txn_stats_top_hour
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_top_hour)
ORDER BY avg_commit_latency_seconds DESC;
Resultado da consulta
fprint read_columns write_constructive_columns write_delete_tables avg_total_latency_seconds avg_commit_latency_seconds avg_bytes
40015598317 [] ["Routes.name", "Cars.model"] ["Users"] 0.006578737 0.006547737 25286
77848338483 [] [] ["Cars", "Routes"] 0.033467418 0.000251418 0
20524969030 ["id", "no"] [] [] 0.001732442 0.000247442 0

Encontre a latência média das transações que leem determinadas colunas

A consulta seguinte devolve as informações de latência média para transações que leem a coluna ADDRESS das estatísticas de 1 hora:

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_total_latency_seconds
FROM spanner_sys.txn_stats_top_hour
WHERE 'ADDRESS' IN UNNEST(read_columns)
ORDER BY avg_total_latency_seconds DESC;
Resultado da consulta
fprint read_columns write_constructive_columns write_delete_tables avg_total_latency_seconds
77848338483 ["ID", "ADDRESS"] [] ["Cars", "Routes"] 0.033467418
40015598317 ["ID", "NAME", "ADDRESS"] [] ["Users"] 0.006578737

Liste as transações pelo número médio de bytes modificados

A seguinte consulta devolve as transações com amostragem na última hora, ordenadas pelo número médio de bytes modificados pela transação.

SELECT fprint,
       read_columns,
       write_constructive_columns,
       write_delete_tables,
       avg_bytes
FROM spanner_sys.txn_stats_top_hour
ORDER BY avg_bytes DESC;
Resultado da consulta
fprint read_columns write_constructive_columns write_delete_tables avg_bytes
40015598317 [] [] ["Users"] 25286
77848338483 [] [] ["Cars", "Routes"] 12005
20524969030 ["ID", "ADDRESS"] [] ["Users"] 10923

Estatísticas agregadas

SPANNER_SYS também contém tabelas para armazenar dados agregados de todas as transações para as quais o Spanner capturou estatísticas num período específico:

  • SPANNER_SYS.TXN_STATS_TOTAL_MINUTE: agregue estatísticas para todas as transações durante intervalos de 1 minuto
  • SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE: agregue estatísticas para todas as transações durante intervalos de 10 minutos
  • SPANNER_SYS.TXN_STATS_TOTAL_HOUR: agregue estatísticas para todas as transações durante intervalos de 1 hora

As tabelas de estatísticas agregadas têm as seguintes propriedades:

  • Cada tabela contém dados para intervalos de tempo não sobrepostos com a duração especificada no nome da tabela.

  • Os intervalos baseiam-se nas horas do relógio. Os intervalos de 1 minuto terminam no minuto, os intervalos de 10 minutos terminam a cada 10 minutos a partir da hora, e os intervalos de 1 hora terminam na hora.

    Por exemplo, às 11:59:30, os intervalos mais recentes disponíveis para consultas SQL sobre estatísticas de transações agregadas são:

    • 1 minuto: 11:58:00–11:58:59
    • 10 minutos: 11:40:00–11:49:59
    • 1 hora: 10:00:00–10:59:59
  • Cada linha contém estatísticas de todas as transações executadas na base de dados durante o intervalo especificado, agregadas. Só existe uma linha por intervalo de tempo.

  • As estatísticas capturadas nas tabelas SPANNER_SYS.TXN_STATS_TOTAL_* podem incluir transações que o Spanner não capturou nas tabelas SPANNER_SYS.TXN_STATS_TOP_*.

  • Algumas colunas nestas tabelas são expostas como métricas no Cloud Monitoring. As métricas expostas são:

    • Contagem de tentativas de confirmação
    • Contagem de novas tentativas de confirmação
    • Participantes da transação
    • Latências das transações
    • Bytes escritos

    Para mais informações, consulte o artigo Métricas do Spanner.

Esquema da tabela

Nome da coluna Tipo Descrição
INTERVAL_END TIMESTAMP Fim do intervalo de tempo em que esta estatística foi capturada.
ATTEMPT_COUNT INT64 O número total de vezes que as transações são tentadas, incluindo as tentativas que são anuladas antes de chamar `commit`.
COMMIT_ATTEMPT_COUNT INT64 Número total de tentativas de confirmação de transações. Tem de corresponder ao número de chamadas para o método commit da transação.
COMMIT_ABORT_COUNT INT64 Número total de tentativas de transação que foram anuladas, incluindo as que foram anuladas antes de chamar o método commit da transação.
COMMIT_RETRY_COUNT INT64 Número de tentativas de confirmação que são novas tentativas de tentativas anteriormente anuladas. Uma transação do Spanner pode ter sido tentada várias vezes antes de ser confirmada devido a contestações de bloqueio ou eventos transitórios. Um número elevado de tentativas em relação às tentativas de confirmação indica que podem existir problemas que vale a pena investigar. Para mais informações, consulte a secção Compreender as transações e as quantidades de commits nesta página.
COMMIT_FAILED_PRECONDITION_COUNT INT64 O número total de tentativas de confirmação de transações que devolveram erros de pré-condição falhada, como violações de índice, a linha já existe, a linha não foi encontrada, etc.UNIQUE
SERIALIZABLE_PESSIMISTIC_TXN_COUNT INT64 Número total de tentativas de transação iniciadas com o nível de isolamento SERIALIZABLE e o bloqueio PESSIMISTIC. É um subconjunto de ATTEMPT_COUNT.
REPEATABLE_READ_OPTIMISTIC_TXN_COUNT INT64 Número total de tentativas de transação iniciadas com o nível de isolamento REPEATABLE READ e o bloqueio OPTIMISTIC. É um subconjunto de ATTEMPT_COUNT.
AVG_PARTICIPANTS FLOAT64 Número médio de participantes em cada tentativa de confirmação. Para saber mais acerca dos participantes, consulte Ciclo de vida das leituras e escritas do Spanner.
AVG_TOTAL_LATENCY_SECONDS FLOAT64 A média de segundos decorridos desde a primeira operação da transação até à confirmação/anulação.
AVG_COMMIT_LATENCY_SECONDS FLOAT64 Média de segundos necessários para realizar a operação de confirmação.
AVG_BYTES FLOAT64 Número médio de bytes escritos pela transação.
TOTAL_LATENCY_DISTRIBUTION ARRAY<STRUCT>

Um histograma da latência total de confirmação, que é o tempo desde a hora de início da primeira operação transacional até à hora de confirmação ou anulação para todas as tentativas de transação.

Se uma transação for anulada várias vezes e, em seguida, for confirmada com êxito, a latência é medida para cada tentativa até à confirmação final bem-sucedida. Os valores são medidos em segundos.

A matriz contém um único elemento e tem o seguinte tipo:
ARRAY<STRUCT<
  COUNT INT64,
  MEAN FLOAT64,
  SUM_OF_SQUARED_DEVIATION FLOAT64,
  NUM_FINITE_BUCKETS INT64,
  GROWTH_FACTOR FLOAT64,
  SCALE FLOAT64,
  BUCKET_COUNTS ARRAY<INT64>>>

Para mais informações sobre os valores, consulte Distribuição.

Para calcular a latência do percentil desejado a partir da distribuição, use a SPANNER_SYS.DISTRIBUTION_PERCENTILE(distribution, n FLOAT64)função, que devolve o percentil n estimado. Por exemplo, consulte a secção Encontre a latência do 99.º percentil para transações.

Para mais informações, consulte o artigo Percentis e métricas com valores de distribuição.

OPERATIONS_BY_TABLE ARRAY<STRUCT>

Impacto das operações INSERT ou UPDATE por todas as transações com base em cada tabela. Isto é indicado pelo número de vezes que as linhas são afetadas e o número de bytes que são escritos.

Esta coluna ajuda a visualizar a carga nas tabelas e fornece estatísticas sobre a taxa à qual as transações escrevem nas tabelas.

Especifique a matriz da seguinte forma:
ARRAY<STRUCT<
  TABLE STRING(MAX),
  INSERT_OR_UPDATE_COUNT INT64,
  INSERT_OR_UPDATE_BYTES INT64>>

Consultas de exemplo

Esta secção inclui vários exemplos de declarações SQL que obtêm estatísticas de transações. Pode executar estas declarações SQL através das bibliotecas de cliente, do gcloud spanner ou da Google Cloud consola.

Encontre o número total de tentativas de confirmação para todas as transações

A consulta seguinte devolve o número total de tentativas de confirmação para todas as transações no intervalo de 1 minuto completo mais recente:

SELECT interval_end,
       commit_attempt_count
FROM spanner_sys.txn_stats_total_minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_total_minute)
ORDER BY interval_end;
Resultado da consulta
interval_end commit_attempt_count
2020-01-17 11:46:00-08:00 21

Tenha em atenção que só existe uma linha no resultado porque as estatísticas agregadas só têm uma entrada por interval_end para qualquer duração.

Encontre a latência de confirmação total em todas as transações

A seguinte consulta devolve a latência de confirmação total em todas as transações nos 10 minutos anteriores:

SELECT (avg_commit_latency_seconds * commit_attempt_count / 60 / 60)
  AS total_commit_latency_hours
FROM spanner_sys.txn_stats_total_10minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_total_10minute);
Resultado da consulta
total_commit_latency_hours
0.8967

Tenha em atenção que só existe uma linha no resultado porque as estatísticas agregadas só têm uma entrada por interval_end para qualquer duração.

Encontre a latência do percentil 99 para transações

A seguinte consulta devolve a latência do percentil 99 para as transações executadas nos 10 minutos anteriores:

SELECT interval_end, avg_total_latency_seconds,
       SPANNER_SYS.DISTRIBUTION_PERCENTILE(total_latency_distribution[OFFSET(0)], 99.0)
  AS percentile_latency
FROM spanner_sys.txn_stats_total_10minute
WHERE interval_end =
  (SELECT MAX(interval_end)
   FROM spanner_sys.txn_stats_total_10minute)
ORDER BY interval_end;

Resultado da consulta
interval_end avg_total_latency_seconds percentile_latency
2022-08-17 11:46:00-08:00 0.34576998305986395 9.00296190476190476

Repare na grande diferença entre a latência média e a latência do percentil 99. A latência do percentil 99 ajuda a identificar possíveis transações atípicas com latência elevada.

Só existe uma linha no resultado porque as estatísticas agregadas só têm uma entrada por interval_end para qualquer duração.

Retenção de dados

No mínimo, o Spanner mantém os dados de cada tabela durante os seguintes períodos:

  • SPANNER_SYS.TXN_STATS_TOP_MINUTE e SPANNER_SYS.TXN_STATS_TOTAL_MINUTE: intervalos que abrangem as 6 horas anteriores.

  • SPANNER_SYS.TXN_STATS_TOP_10MINUTE e SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE: intervalos que abrangem os 4 dias anteriores.

  • SPANNER_SYS.TXN_STATS_TOP_HOUR e SPANNER_SYS.TXN_STATS_TOTAL_HOUR: intervalos que abrangem os 30 dias anteriores.

As estatísticas de transações no Spanner dão informações sobre a forma como uma aplicação está a usar a base de dados e são úteis quando investiga problemas de desempenho. Por exemplo, pode verificar se existem transações de execução lenta que possam estar a causar contenção ou pode identificar potenciais origens de carga elevada, como grandes volumes de atualizações a uma coluna específica. Através dos passos seguintes, vamos mostrar-lhe como usar as estatísticas de transações para investigar conflitos na sua base de dados.

Compreenda as transações e as quantidades de compromissos

Pode ter de tentar uma transação do Spanner várias vezes antes de a confirmar. Isto ocorre mais frequentemente quando duas transações tentam trabalhar nos mesmos dados ao mesmo tempo e uma das transações tem de ser anulada para preservar a propriedade de isolamento da transação. Outros eventos transitórios que também podem fazer com que uma transação seja anulada incluem:

  • Problemas de rede temporários.

  • As alterações ao esquema da base de dados estão a ser aplicadas enquanto uma transação está em processo de confirmação.

  • A instância do Spanner não tem capacidade para processar todos os pedidos que está a receber.

Nestes cenários, um cliente deve tentar novamente a transação anulada até que seja confirmada com êxito ou expire. Para os utilizadores das bibliotecas de cliente oficiais do Spanner, cada biblioteca implementou um mecanismo de nova tentativa automática. Se estiver a usar uma versão personalizada do código do cliente, envolva os compromissos de transação num ciclo de repetição.

Uma transação do Spanner também pode ser anulada devido a um erro não repetível, como um tempo limite excedido da transação, problemas de autorização ou um nome de tabela/coluna inválido. Não é necessário tentar novamente essas transações, e a biblioteca do cliente do Spanner devolve o erro imediatamente.

A tabela seguinte descreve alguns exemplos de como COMMIT_ATTEMPT_COUNT, COMMIT_ABORT_COUNT e COMMIT_RETRY_COUNT são registados em diferentes cenários.

Cenário COMMIT_ATTEMPT_COUNT COMMIT_ABORT_COUNT COMMIT_RETRY_COUNT
Transação confirmada com êxito na primeira tentativa. 1 0 0
A transação foi interrompida devido a um erro de tempo limite. 1 1 0
Transação anulada devido a um problema de rede temporário e confirmada com êxito após uma nova tentativa. 2 1 1
5 transações com a mesma FPRINT são executadas num intervalo de 10 minutos. 3 das transações foram confirmadas com êxito na primeira tentativa, enquanto 2 transações foram anuladas e, em seguida, confirmadas com êxito na primeira nova tentativa. 7 2 2

Os dados nas tabelas transactions-stats são dados agregados para um intervalo de tempo. Para um intervalo específico, é possível que uma transação seja anulada e que a repetição ocorra em torno dos limites e se enquadre em diferentes grupos. Como resultado, num intervalo de tempo específico, as anulações e as novas tentativas podem não ser iguais.

Estas estatísticas foram concebidas para a resolução de problemas e a introspeção e não é garantido que sejam 100% precisas. As estatísticas são agregadas na memória antes de serem armazenadas em tabelas do Spanner. Durante uma atualização ou outras atividades de manutenção, os servidores do Spanner podem ser reiniciados, o que afeta a precisão dos números.

Resolva contestações de bases de dados com estatísticas de transações

Pode usar o código SQL ou o painel de controlo Estatísticas de transações para ver as transações na sua base de dados que podem causar latências elevadas devido a contestações de bloqueios.

Os tópicos seguintes mostram como pode investigar essas transações através do código SQL.

Selecione um período para investigar

Pode encontrar esta informação na aplicação que está a usar o Spanner.

Para efeitos deste exercício, vamos supor que o problema começou a ocorrer por volta das 17:20 do dia 17 de maio de 2020.

Pode usar etiquetas de transações para identificar a origem da transação e estabelecer uma correlação entre a tabela de estatísticas de transações e as tabelas de estatísticas de bloqueios para uma resolução de problemas de contenção de bloqueios eficaz. Leia mais em Resolução de problemas com etiquetas de transação.

Recolher estatísticas de transações para o período selecionado

Para iniciar a nossa investigação, vamos consultar a tabela TXN_STATS_TOTAL_10MINUTE em torno do início do problema. Os resultados desta consulta mostram-nos como a latência e outras estatísticas de transações mudaram durante esse período.

Por exemplo, a seguinte consulta devolve as estatísticas de transações agregadas de 4:30 pm a 7:40 pm (inclusive).

SELECT
  interval_end,
  ROUND(avg_total_latency_seconds,4) as avg_total_latency_seconds,
  commit_attempt_count,
  commit_abort_count
FROM SPANNER_SYS.TXN_STATS_TOTAL_10MINUTE
WHERE
  interval_end >= "2020-05-17T16:40:00"
  AND interval_end <= "2020-05-17T19:40:00"
ORDER BY interval_end;

A tabela seguinte apresenta exemplos de dados devolvidos pela nossa consulta.

interval_end avg_total_latency_seconds commit_attempt_count commit_abort_count
2020-05-17 16:40:00-07:00 0,0284 315691 5170
2020-05-17 16:50:00-07:00 0,0250 302124 3828
2020-05-17 17:00:00-07:00 0,0460 346087 11382
2020-05-17 17:10:00-07:00 0,0864 379964 33826
2020-05-17 17:20:00-07:00 0,1291 390343 52549
2020-05-17 17:30:00-07:00 0,1314 456455 76392
2020-05-17 17:40:00-07:00 0,1598 507774 121458
2020-05-17 17:50:00-07:00 0,1641 516587 115875
2020-05-17 18:00:00-07:00 0,1578 552711 122626
2020-05-17 18:10:00-07:00 0,1750 569460 154205
2020-05-17 18:20:00-07:00 0,1727 613571 160772
2020-05-17 18:30:00-07:00 0,1588 601994 143044
2020-05-17 18:40:00-07:00 0,2025 604211 170019
2020-05-17 18:50:00-07:00 0,1615 601622 135601
2020-05-17 19:00:00-07:00 0,1653 596804 129511
2020-05-17 19:10:00-07:00 0,1414 560023 112247
2020-05-17 19:20:00-07:00 0,1367 570864 100596
2020-05-17 19:30:00-07:00 0,0894 539729 65316
2020-05-17 19:40:00-07:00 0,0820 479151 40398

Aqui, vemos que a latência agregada e a contagem de anulações são mais elevadas nos períodos realçados. Podemos escolher qualquer intervalo de 10 minutos em que a latência agregada e/ou a contagem de anulações sejam elevadas. Vamos escolher o intervalo que termina a 2020-05-17T18:40:00 e usá-lo no passo seguinte para identificar que transações estão a contribuir para a elevada latência e a contagem de anulações.

Identifique transações que estão a sofrer uma latência elevada

Vamos consultar a tabela TXN_STATS_TOP_10MINUTE para o intervalo que foi selecionado no passo anterior. Com estes dados, podemos começar a identificar as transações que estão a ter uma latência elevada e/ou um número elevado de anulações.

Execute a seguinte consulta para obter as transações com maior impacto no desempenho por ordem descendente da latência total para o nosso intervalo de exemplo que termina a 2020-05-17T18:40:00.

SELECT
  interval_end,
  fprint,
  ROUND(avg_total_latency_seconds,4) as avg_total_latency_seconds,
  ROUND(avg_commit_latency_seconds,4) as avg_commit_latency_seconds,
  commit_attempt_count,
  commit_abort_count,
  commit_retry_count
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  interval_end = "2020-05-17T18:40:00"
ORDER BY avg_total_latency_seconds DESC;
interval_end fprint avg_total_latency_seconds avg_commit_latency_seconds commit_attempt_count commit_abort_count commit_retry_count
2020-05-17 18:40:00-07:00 15185072816865185658 0.3508 0,0139 278802 142205 129884
2020-05-17 18:40:00-07:00 15435530087434255496 0,1633 0,0142 129012 27177 24559
2020-05-17 18:40:00-07:00 14175643543447671202 0,1423 0,0133 5357 636 433
2020-05-17 18:40:00-07:00 898069986622520747 0,0198 0,0158 6 0 0
2020-05-17 18:40:00-07:00 10510121182038036893 0,0168 0,0125 7 0 0
2020-05-17 18:40:00-07:00 9287748709638024175 0,0159 0,0118 4269 1 0
2020-05-17 18:40:00-07:00 7129109266372596045 0,0142 0,0102 182227 0 0
2020-05-17 18:40:00-07:00 15630228555662391800 0,0120 0,0107 58 0 0
2020-05-17 18:40:00-07:00 7907238229716746451 0,0108 0,0097 65 0 0
2020-05-17 18:40:00-07:00 10158167220149989178 0,0095 0,0047 3454 0 0
2020-05-17 18:40:00-07:00 9353100217060788102 0,0093 0,0045 725 0 0
2020-05-17 18:40:00-07:00 9521689070912159706 0,0093 0,0045 164 0 0
2020-05-17 18:40:00-07:00 11079878968512225881 0,0064 0,0019 65 0 0

Podemos ver claramente que a primeira linha (realçada) na tabela anterior mostra uma transação com uma latência elevada devido a um número elevado de anulações de confirmação. Também podemos ver um número elevado de novas tentativas de consolidação, o que indica que as consolidações anuladas foram posteriormente repetidas. No passo seguinte, vamos investigar mais a fundo para ver o que está a causar este problema.

Identifique as colunas envolvidas numa transação com latência elevada

Neste passo, vamos verificar se as transações com latência elevada estão a funcionar no mesmo conjunto de colunas ao obter dados read_columns, write_constructive_columns e write_delete_tables para transações com uma contagem de anulações elevada. O valor de FPRINT também vai ser útil no passo seguinte.

SELECT
  fprint,
  read_columns,
  write_constructive_columns,
  write_delete_tables
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  interval_end = "2020-05-17T18:40:00"
ORDER BY avg_total_latency_seconds DESC LIMIT 3;
fprint read_columns write_constructive_columns write_delete_tables
15185072816865185658 [TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.shares] [TestHigherLatency._exists,TestHigherLatency.shares,TestHigherLatency_lang_status_score_index.shares] []
15435530087434255496 [TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.likes,globalTagAffinity.score] [TestHigherLatency._exists,TestHigherLatency.likes,TestHigherLatency_lang_status_score_index.likes] []
14175643543447671202 [TestHigherLatency._exists,TestHigherLatency.lang_status,TestHigherLatency.score,globalTagAffinity.ugcCount] [TestHigherLatency._exists,TestHigherLatency.ugcCount,TestHigherLatency_lang_status_score_index.ugcCount] []

Conforme o resultado apresentado na tabela anterior, as transações com a latência total média mais elevada estão a ler as mesmas colunas. Também podemos observar alguma contenção de escrita, uma vez que as transações estão a escrever na mesma coluna, ou seja, TestHigherLatency._exists.

Determinar como o desempenho das transações mudou ao longo do tempo

Podemos ver como as estatísticas associadas a esta forma de transação mudaram ao longo de um período. Use a seguinte consulta, em que $FPRINT é a impressão digital da transação de alta latência do passo anterior.

SELECT
  interval_end,
  ROUND(avg_total_latency_seconds, 3) AS latency,
  ROUND(avg_commit_latency_seconds, 3) AS commit_latency,
  commit_attempt_count,
  commit_abort_count,
  commit_retry_count,
  commit_failed_precondition_count,
  avg_bytes
FROM SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  interval_end >= "2020-05-17T16:40:00"
  AND interval_end <= "2020-05-17T19:40:00"
  AND fprint = $FPRINT
ORDER BY interval_end;
interval_end latência commit_latency commit_attempt_count commit_abort_count commit_retry_count commit_failed_precondition_count avg_bytes
2020-05-17 16:40:00-07:00 0,095 0,010 53230 4752 4330 0 91
2020-05-17 16:50:00-07:00 0,069 0,009 61264 3589 3364 0 91
2020-05-17 17:00:00-07:00 0,150 0,010 75868 10557 9322 0 91
2020-05-17 17:10:00-07:00 0,248 0,013 103151 30220 28483 0 91
2020-05-17 17:20:00-07:00 0,310 0,012 130078 45655 41966 0 91
2020-05-17 17:30:00-07:00 0,294 0,012 160064 64930 59933 0 91
2020-05-17 17:40:00-07:00 0,315 0,013 209614 104949 96770 0 91
2020-05-17 17:50:00-07:00 0,322 0,012 215682 100408 95867 0 90
2020-05-17 18:00:00-07:00 0,310 0,012 230932 106728 99462 0 91
2020-05-17 18:10:00-07:00 0,309 0,012 259645 131049 125889 0 91
2020-05-17 18:20:00-07:00 0,315 0,013 272171 137910 129411 0 90
2020-05-17 18:30:00-07:00 0,292 0,013 258944 121475 115844 0 91
2020-05-17 18:40:00-07:00 0,350 0,013 278802 142205 134229 0 91
2020-05-17 18:50:00-07:00 0,302 0,013 256259 115626 109756 0 91
2020-05-17 19:00:00-07:00 0,315 0,014 250560 110662 100322 0 91
2020-05-17 19:10:00-07:00 0,271 0,014 238384 99025 90187 0 91
2020-05-17 19:20:00-07:00 0,273 0,014 219687 84019 79874 0 91
2020-05-17 19:30:00-07:00 0,198 0,013 195357 59370 55909 0 91
2020-05-17 19:40:00-07:00 0,181 0,013 167514 35705 32885 0 91

No resultado acima, podemos observar que a latência total é elevada para o período realçado. Além disso, sempre que a latência total é elevada, commit_attempt_count commit_abort_count e commit_retry_count também são elevados, apesar de a latência de confirmação (commit_latency) não ter sofrido grandes alterações. Uma vez que as confirmações de transações estão a ser anuladas com maior frequência, as tentativas de confirmação também são elevadas devido às repetições de confirmações.

Conclusão

Neste exemplo, verificámos que a elevada quantidade de anulações de compromissos foi a causa da elevada latência. O passo seguinte é analisar as mensagens de erro de anulação de confirmação recebidas pela aplicação para saber o motivo das anulações. Ao inspecionar os registos na aplicação, vemos que a aplicação alterou efetivamente a respetiva carga de trabalho durante este período, ou seja, surgiu outra forma de transação com um valor attempts_per_second elevado, e essa transação diferente (talvez uma tarefa de limpeza noturna) foi responsável pelos conflitos de bloqueio adicionais.

Identifique transações que não foram repetidas corretamente

A seguinte consulta devolve as transações com amostragem nos últimos dez minutos que têm uma contagem de anulações de confirmação elevada, mas sem novas tentativas.

SELECT
  *
FROM (
  SELECT
    fprint,
    SUM(commit_attempt_count) AS total_commit_attempt_count,
    SUM(commit_abort_count) AS total_commit_abort_count,
    SUM(commit_retry_count) AS total_commit_retry_count
  FROM
    SPANNER_SYS.TXN_STATS_TOP_10MINUTE
  GROUP BY
    fprint )
WHERE
  total_commit_retry_count = 0
  AND total_commit_abort_count > 0
ORDER BY
  total_commit_abort_count DESC;
fprint total_commit_attempt_count total_commit_abort_count total_commit_retry_count
1557557373282541312 3367894 44232 0
5776062322886969344 13566 14 0

Podemos ver que a transação com a impressão digital 1557557373282541312 foi anulada 44232 vezes, mas nunca foi repetida. Isto parece suspeito porque a contagem de abortos é elevada e é improvável que todos os abortos tenham sido causados por um erro não repetível. Por outro lado, a transação com a impressão digital 5776062322886969344 é menos suspeita porque a contagem total de anulações não é assim tão elevada.

A seguinte consulta devolve mais detalhes acerca da transação com a impressão digital 1557557373282541312,incluindo read_columns, write_constructive_columns e write_delete_tables. Estas informações ajudam a identificar a transação no código do cliente, onde a lógica de repetição pode ser revista para este cenário.

SELECT
  interval_end,
  fprint,
  read_columns,
  write_constructive_columns,
  write_delete_tables,
  commit_attempt_count,
  commit_abort_count,
  commit_retry_count
FROM
  SPANNER_SYS.TXN_STATS_TOP_10MINUTE
WHERE
  fprint = 1557557373282541312
ORDER BY
  interval_end DESC;
interval_end fprint read_columns write_constructive_columns write_delete_tables commit_attempt_count commit_abort_count commit_retry_count
2021-01-27T18:30:00Z 1557557373282541312 ["Singers._exists"] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 805228 1839 0
2021-01-27T18:20:00Z 1557557373282541312 ["Singers._exists"] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 1034429 38779 0
2021-01-27T18:10:00Z 1557557373282541312 ["Singers._exists"] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 833677 2266 0
2021-01-27T18:00:00Z 1557557373282541312 ["Singers._exists"] ['Singers.FirstName', 'Singers.LastName', 'Singers._exists'] [] 694560 1348 0

Podemos ver que a transação envolve uma leitura da coluna oculta Singers._exists para verificar a existência de uma linha. A transação também é escrita nas colunas Singers.FirstName e Singer.LastName. Estas informações podem ajudar a determinar se o mecanismo de nova tentativa de transação implementado na sua biblioteca de cliente personalizada está a funcionar conforme esperado.

O que se segue?