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
:
A página do Spanner Studio de uma base de dados na Google Cloud consola.
O comando
gcloud spanner databases execute-sql
.O painel de controlo Estatísticas de transações.
O método
executeSql
ou o métodoexecuteStreamingSql
.
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:
Para calcular a latência do percentil desejado a partir da distribuição,
use a 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
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:
|
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 minutoSPANNER_SYS.TXN_STATS_TOTAL_10MINUTE
: agregue estatísticas para todas as transações durante intervalos de 10 minutosSPANNER_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 tabelasSPANNER_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:
Para calcular a latência do percentil desejado a partir da distribuição,
use a 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
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:
|
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
eSPANNER_SYS.TXN_STATS_TOTAL_MINUTE
: intervalos que abrangem as 6 horas anteriores.SPANNER_SYS.TXN_STATS_TOP_10MINUTE
eSPANNER_SYS.TXN_STATS_TOTAL_10MINUTE
: intervalos que abrangem os 4 dias anteriores.SPANNER_SYS.TXN_STATS_TOP_HOUR
eSPANNER_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?
- Saiba mais acerca de outras ferramentas de introspeção.
- Saiba mais sobre outras informações que o Spanner armazena para cada base de dados nas tabelas do esquema de informações da base de dados.
- Saiba mais sobre as práticas recomendadas de SQL para o Spanner.
- Saiba mais sobre a investigação da utilização elevada da CPU.