Se a instância do Hologres apresentar resposta lenta ou consultas demoradas, os logs de consultas lentas ajudarão a identificar e diagnosticar o problema. Este tópico explica como consultar a tabela hologres.hg_query_log, interpretar os principais campos e usar SQL de diagnóstico para localizar problemas de desempenho.
Guia de versões
|
Versão |
Alteração |
|
V0.10 |
Introdução dos logs de consultas lentas. Logs de consultas com FALHA não incluem estatísticas de tempo de execução (memória, leituras de disco, volume de dados lidos, tempo de CPU ou |
|
V2.2 |
Adição da coluna |
|
V2.2.7 |
Alteração do valor padrão de |
|
V3.0.2 |
Inclusão de registros agregados para operações DML e DQL executadas em menos de 100 ms. Também foram adicionados os campos |
|
V3.0.27 |
Suporte à modificação do período de retenção de logs via |
Esse recurso requer o Hologres V0.10 ou posterior. Para verificar a versão da sua instância, acesse a página de detalhes da instância no console do Hologres. Para atualizar uma instância mais antiga, consulte Erros comuns de preparação de atualização ou entre em contato com o suporte do Hologres. Para mais informações, consulte Como obter mais suporte online? .
Limitações
Os logs de consultas lentas são retidos por um mês por padrão.
Uma única consulta retorna no máximo 10.000 entradas de log de consultas lentas. Alguns campos possuem limites de tamanho — consulte as descrições dos campos na seção da tabela
hg_query_log.Os logs de consultas lentas fazem parte do warehouse de metadados do Hologres. Uma falha na busca desses logs não afeta suas consultas de negócio, e a disponibilidade dos logs não é coberta pelo Acordo de Nível de Serviço (SLA) do Hologres.
Como funciona
O Hologres armazena logs de consultas lentas na tabela de sistema hologres.hg_query_log. A tabela registra apenas instruções SQL concluídas — consultas ainda em andamento não são gravadas nela. Esse comportamento é consistente nas versões V2, V3 e posteriores.
O que é registrado:
Após a atualização para a V0.10: consultas DML lentas com duração superior a 100 ms e todas as operações DDL.
A partir da V3.0.2: além dos registros detalhados para consultas acima de 100 ms, registros agregados também são gravados para consultas DQL e DML concluídas em menos de 100 ms.
Funcionamento da agregação (V3.0.2+):
Para consultas rápidas (menos de 100 ms), o sistema agrupa consultas DQL e DML bem-sucedidas que compartilham a mesma impressão digital SQL (digest). A chave de agregação é composta por: server_addr, usename, datname, warehouse_id, application_name e digest. Cada conexão libera um registro agregado por minuto.
A tabela hg_query_log
A tabela possui dois tipos de registros, que compartilham o mesmo esquema, mas têm semânticas diferentes:
|
Campo |
Tipo de dado |
Registros detalhados (acima de 100 ms) |
Registros agregados (abaixo de 100 ms) |
|
|
text |
Nome de usuário da consulta. |
Nome de usuário da consulta. |
|
|
text |
|
Sempre |
|
|
text |
ID exclusivo da consulta. Uma consulta com falha sempre possui um |
O |
|
|
text |
Impressão digital SQL (hash MD5). Adicionado na V2.2. Para mais informações, consulte Impressão digital SQL. |
Impressão digital SQL. |
|
|
text |
Nome do banco de dados. |
Nome do banco de dados. |
|
|
text |
Tipo de consulta: DML (COPY, DELETE, INSERT, SELECT, UPDATE), DDL (ALTER TABLE, BEGIN, COMMENT, COMMIT, CREATE FOREIGN TABLE, CREATE TABLE, DROP FOREIGN TABLE, DROP TABLE, IMPORT FOREIGN SCHEMA, ROLLBACK, TRUNCATE TABLE) ou Outro (CALL, CREATE EXTENSION, EXPLAIN, GRANT, SECURITY LABEL). |
O |
|
|
integer |
ID do warehouse virtual usado na consulta. |
O ID do warehouse virtual da primeira consulta no período de agregação. |
|
|
integer |
Nome do warehouse virtual usado na consulta. |
O nome do warehouse virtual da primeira consulta no período de agregação. |
|
|
integer |
Adicionado na V3.0.2. O ID do cluster dentro do warehouse virtual. Os IDs de cluster começam em 1. |
O ID do cluster da primeira consulta no período de agregação. |
|
|
integer |
Duração total da consulta em milissegundos. Dividida em três etapas — veja abaixo. |
Duração média de todas as consultas no período de agregação. |
|
|
text |
Mensagem de erro para consultas com falha. |
Vazio. |
|
|
timestamptz |
Hora de início da consulta. |
O |
|
|
text |
Data de início da consulta. |
O |
|
|
text |
Texto da consulta. Máximo de 51.200 caracteres; consultas mais longas são truncadas. |
O texto da primeira consulta no período de agregação. |
|
|
bigint |
Linhas retornadas. Para INSERT, o número de linhas inseridas. |
Valor médio de todas as consultas no período de agregação. |
|
|
bigint |
Bytes retornados. |
Valor médio. |
|
|
bigint |
Linhas lidas (não exato; pode diferir das linhas realmente verificadas quando um índice bitmap é usado). |
Valor médio. |
|
|
bigint |
Bytes lidos. |
Valor médio. |
|
|
bigint |
Linhas afetadas pela instrução DML. |
Valor médio. |
|
|
bigint |
Bytes afetados pela instrução DML. |
Valor médio. |
|
|
bigint |
Pico cumulativo de uso de memória em todos os nós (não exato). Reflete a quantidade de dados lidos pela consulta. |
Valor médio. |
|
|
bigint |
Estimativa de bytes transferidos pela rede (não exato). |
Valor médio. |
|
|
bigint |
Tempo total de CPU em milissegundos em todas as tarefas de computação (não exato). Reflete a complexidade da consulta. |
Valor médio. |
|
|
bigint |
Número de lotes de registros lidos do disco. Reflete a frequência de falhas de cache. |
Valor médio. |
|
|
integer |
ID do processo do serviço de consulta. |
ID do processo da primeira consulta no período de agregação. |
|
|
text |
Identificador da aplicação. Consulte Valores de application_name. |
Tipo de aplicação. |
|
|
text[] |
Mecanismo de execução utilizado. Consulte Tipos de mecanismo. |
O mecanismo da primeira consulta no período de agregação. |
|
|
text |
Endereço IP de origem (o IP de saída da aplicação, não necessariamente o IP real da aplicação). |
O endereço de origem da primeira consulta no período de agregação. |
|
|
text |
Tabela na qual os dados são gravados. |
O destino de gravação da primeira consulta no período de agregação. |
|
|
text[] |
Tabelas das quais os dados são lidos. |
As fontes de leitura da primeira consulta no período de agregação. |
|
|
text |
ID da sessão. |
O ID da sessão da primeira consulta no período de agregação. |
|
|
timestamptz |
Hora em que a conexão foi estabelecida. |
Hora de início da sessão em todas as consultas no período de agregação. |
|
|
text |
ID do comando ou instrução. |
ID do comando em todas as consultas no período de agregação. |
|
|
integer |
Tempo para gerar o plano de execução da consulta (ms). Valores altos indicam uma instrução SQL complexa. |
Tempo de geração de plano em todas as consultas no período de agregação. |
|
|
integer |
Tempo de inicialização da consulta (ms). Valores altos indicam que a consulta está aguardando bloqueios ou recursos. |
Tempo de inicialização em todas as consultas no período de agregação. |
|
|
integer |
Tempo de execução da consulta (ms). Valores altos indicam que a computação é grande e a execução leva muito tempo. |
Tempo de execução em todas as consultas no período de agregação. |
|
|
text |
Outros detalhes de tempo, incluindo: |
Custo estendido da primeira consulta no período de agregação. |
|
|
text |
Plano de execução da consulta. Máximo de 102.400 caracteres; planos mais longos são truncados. Controlado por |
Plano de execução da primeira consulta no período de agregação. |
|
|
text |
Estatísticas de execução da consulta. Máximo de 102.400 caracteres. Controlado por |
Estatísticas de execução da primeira consulta no período de agregação. |
|
|
text |
Dados de visualização do plano de consulta. |
Dados de visualização da primeira consulta no período de agregação. |
|
|
text |
Informações estendidas da consulta em formato JSON. Máximo de 10.240 caracteres; valores mais longos são truncados. |
Informações estendidas da primeira consulta no período de agregação. |
|
|
text[] |
Informações estendidas da consulta em formato de array. Inclui |
Informações estendidas da primeira consulta no período de agregação. |
|
|
INT |
Sempre |
Número de consultas com a mesma chave de agregação no período de agregação. |
|
|
JSONB |
Vazio. Adicionado na V3.0.2. |
Estatísticas MIN, MAX e AVG para campos numéricos ( |
|
|
JSONB |
Informações estendidas sobre Query Queue e Serverless Computing. Consulte Valores de extended_info. |
Vazio. |
Entendendo o detalhamento da duration:
O campo duration representa o tempo total da consulta e é composto por três etapas:
|
Etapa |
Campo |
Significado |
Quando é alto |
|
Geração de plano |
|
Tempo para compilar o plano de execução |
A instrução SQL é complexa |
|
Inicialização |
|
Tempo antes do início da execução |
Aguardando bloqueios ou recursos |
|
Execução |
|
Tempo para executar a consulta |
A computação é grande e a execução leva muito tempo |
Use extended_cost para obter detalhes adicionais de tempo além dessas três etapas.
Valores de application_name
|
Origem |
Formato |
|
Realtime Compute for Apache Flink (VVR) |
|
|
Flink open source |
|
|
Sincronização de leitura offline do DataWorks |
|
|
Sincronização de gravação offline do DataWorks |
|
|
Sincronização em tempo real do DataWorks |
|
|
HoloWeb |
|
|
Acesso a tabela externa do MaxCompute |
|
|
Auto Analyze |
|
|
Quick BI |
|
|
Agendamento do DataWorks |
|
|
Data Security Guard |
|
Para outras aplicações, defina explicitamente o application_name na string de conexão.
Tipos de mecanismo
|
Mecanismo |
Descrição |
|
HQE |
Mecanismo nativo proprietário do Hologres. A maioria das consultas usa o HQE para alta eficiência de execução. |
|
PQE |
O mecanismo PostgreSQL. Quando o PQE aparece, alguns operadores SQL não são suportados nativamente pelo HQE. Reescrevê-los conforme descrito em Otimizar o desempenho de consultas pode melhorar o desempenho. |
|
FixedQE |
O mecanismo de execução para Fixed Plan. Lida eficientemente com SQL do tipo serving, como leituras pontuais, gravações pontuais e PrefixScan. Anteriormente chamado de SDK (renomeado na V2.2). Para mais informações, consulte Acelerar a execução de SQL com Fixed Plan. |
|
PG |
Computação local frontend para consultas de metadados em tabelas de sistema. Não lê dados de tabelas de usuário. Instruções DDL também usam o PG. |
Valores de extended_info
O campo extended_info registra a origem da execução do Serverless Computing:
|
**Valor de |
Significado |
|
|
A consulta foi enviada manualmente para execução em recursos Serverless, independente da Query Queue. |
|
|
Todas as consultas na fila de consultas especificada são executadas em recursos Serverless. Consulte Usar recursos do Serverless Computing para executar consultas em uma fila de consultas. |
|
|
A consulta foi reexecutada automaticamente em recursos Serverless pelo recurso de controle de consultas grandes da Query Queue. Consulte Controle de consultas grandes. |
Quando serverless_computing_source é query_queue_rerun, o campo query_id_of_triggered_rerun também aparece, mostrando o ID da consulta original da instrução reexecutada.
Pré-requisitos
Para visualizar logs de consultas lentas, você precisa de uma das seguintes permissões:
View logs for all databases in an instance:
-
Superusuário: Execute o seguinte comando. Substitua
Alibaba Cloud account IDpelo nome de usuário real. Para usuários RAM, usep4_AccountID(ID da conta, não o nome do usuário RAM).ALTER USER "Alibaba Cloud account ID" SUPERUSER; -
Grupo pg_read_all_stats (para não superusuários): Solicite a um superusuário que adicione você a este grupo.
-- Standard PostgreSQL authorization GRANT pg_read_all_stats TO "Alibaba Cloud account ID"; -- Simple permission model (SPM) CALL spm_grant('pg_read_all_stats', 'Alibaba Cloud account ID'); -- Schema-level permission model (SLPM) CALL slpm_grant('pg_read_all_stats', 'Alibaba Cloud account ID');
View logs for the current database only:
Ative o SPM ou SLPM e adicione o usuário à função db_admin.
-- SPM
CALL spm_grant('<db_name>_admin', 'Alibaba Cloud account ID');
-- SLPM
CALL slpm_grant('<db_name>.admin', 'Alibaba Cloud account ID');
Usuários regulares podem visualizar apenas suas próprias consultas no banco de dados atual, sem necessidade de configuração adicional.
Visualizar logs de consultas lentas
O Hologres oferece duas maneiras de visualizar logs de consultas lentas. Use o HoloWeb para exploração visual e SQL para filtros personalizados, intervalos de tempo e exportação.
|
Método |
Mais indicado para |
Restrições |
|
HoloWeb |
Exploração visual e análise de tendências |
Apenas superusuário; apenas últimos 7 dias |
|
SQL (tabela |
Intervalos de tempo personalizados, filtragem e exportação |
Requer permissões adequadas |
Visualizar no HoloWeb
Faça login no console do HoloWeb.
Na barra de navegação superior, clique em Diagnostics and Optimization.
No painel de navegação à esquerda, clique em Historical Slow Query.
Defina as condições de consulta na parte superior da página Historical Slow Query. Para uma descrição dos parâmetros, consulte Consultas Lentas Históricas.
-
Clique em Search. Os resultados aparecem em duas áreas:
Query Trend Analysis: mostra a frequência de consultas lentas e com falha ao longo do tempo, ajudando a identificar períodos problemáticos.
Queries: lista informações detalhadas para cada consulta lenta ou com falha. Clique em Customize Columns para escolher quais colunas exibir.
Consultar com SQL
Consulte a tabela hologres.hg_query_log diretamente para total flexibilidade. Consulte Diagnosticar consultas para exemplos de SQL prontos para uso.
Impressão digital SQL
A partir da V2.2, a coluna digest em hg_query_log armazena uma impressão digital SQL para cada consulta. Para SELECT, INSERT, DELETE e UPDATE, o Hologres calcula um hash MD5 como impressão digital.
Quando usar digest versus query_id:
Use
digestpara agrupar e analisar consultas do mesmo tipo — por exemplo, para descobrir quais padrões de consulta consomem mais CPU em média.Use
query_idpara rastrear uma execução específica de consulta — por exemplo, para recuperar os detalhes completos de uma consulta com falha específica.
Como as impressões digitais são calculadas:
As impressões digitais são coletadas apenas para SELECT, INSERT, DELETE e UPDATE.
Espaços em branco são ignorados (espaços, quebras de linha, tabulações).
Valores constantes são ignorados:
SELECT * FROM t WHERE a > 1eSELECT * FROM t WHERE a > 2produzem a mesma impressão digital.Contagens de elementos de array são ignoradas:
WHERE a IN (1, 2)eWHERE a IN (3, 4, 5)produzem a mesma impressão digital.Para INSERT com dados constantes, a impressão digital não é afetada pelo número de linhas inseridas.
Maiúsculas e minúsculas seguem as regras de consulta do Hologres.
A impressão digital inclui o nome do banco de dados e o esquema totalmente qualificado, portanto
SELECT * FROM teSELECT * FROM public.ttêm a mesma impressão digital apenas quandotestá no esquemapublice ambas as consultas referenciam a mesma tabela.
Diagnosticar consultas
Os exemplos de SQL a seguir cobrem os cenários de diagnóstico mais comuns. Todas as consultas têm como alvo hologres.hg_query_log.
Contar todas as consultas no log (padrão: último mês):
SELECT count(*) FROM hologres.hg_query_log;
Exemplo de saída — 44 consultas lentas no último mês:
count
-------
44
(1 row)
Contar consultas lentas por usuário:
SELECT usename AS "User",
count(1) AS "Query count"
FROM hologres.hg_query_log
GROUP BY usename
ORDER BY count(1) DESC;
Exemplo de saída:
User | Query count
---------------------+-------------
1111111111111111 | 27
2222222222222222 | 11
3333333333333333 | 4
4444444444444444 | 2
(4 rows)
Localizar uma consulta específica por ID:
SELECT * FROM hologres.hg_query_log WHERE query_id = '13001450118416xxxx';
Para uma descrição dos campos retornados, consulte A tabela hg_query_log.
Encontrar consultas intensivas em recursos nos últimos 10 minutos:
Ajuste o intervalo para corresponder à janela de tempo desejada.
SELECT status AS "Status",
duration AS "Duration (ms)",
query_start AS "Start time",
(read_bytes / 1048576)::text || ' MB' AS "Data read",
(memory_bytes / 1048576)::text || ' MB' AS "Memory",
(shuffle_bytes / 1048576)::text || ' MB' AS "Shuffle",
(cpu_time_ms / 1000)::text || ' s' AS "CPU time",
physical_reads AS "Disk reads",
query_id AS "Query ID",
query::char(30)
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '10 min'
ORDER BY duration DESC,
read_bytes DESC,
shuffle_bytes DESC,
memory_bytes DESC,
cpu_time_ms DESC,
physical_reads DESC
LIMIT 100;
Exemplo de saída:
Status | Duration (ms) | Start time | Data read | Memory | Shuffle | CPU time | Disk reads | Query ID | query
---------+---------------+------------------------+-----------+--------+---------+----------+------------+--------------------+--------------------------------
SUCCESS | 149 | 2021-03-30 23:45:01+08 | 0 MB | 25 MB | 454 MB | 321 s | 0 | 13001450118416xxxx | explain analyze SELECT * FROM
SUCCESS | 137 | 2021-03-30 23:49:18+08 | 247 MB | 21 MB | 213 MB | 803 s | 7771 | 13001491818416xxxx | explain analyze SELECT * FROM
FAILED | 53 | 2021-03-30 23:48:43+08 | 0 MB | 0 MB | 0 MB | 0 s | 0 | 13001484318416xxxx | SELECT ds::bigint / 0 FROM pub
(3 rows)
Cenário: Diagnosticar alto uso de CPU ou memória após atualização de versão da instância
Esta consulta é particularmente útil quando o uso de CPU ou memória aumenta abruptamente após a atualização da instância do Hologres para uma nova versão. Para identificar as consultas que causam o alto consumo de recursos:
Ajuste o intervalo de tempo na cláusula
WHEREpara cobrir o período em que o uso de CPU ou memória estava anormalmente alto. Por exemplo, substituainterval '10 min'por um intervalo que corresponda à janela de tempo do pico.Adicione
ORDER BY cpu_time_ms DESCpara encontrar consultas intensivas em CPU, ouORDER BY memory_bytes DESCpara encontrar consultas intensivas em memória.Verifique as colunas
query_id,usenameequerynos resultados para identificar as consultas específicas e seus proprietários, e então analise e otimize essas consultas adequadamente.
Detalhar a duração por etapa:
Use isto para identificar qual etapa (optimization_cost, start_query_cost ou get_next_cost) responde pela maior parte do atraso. Consulte a tabela de detalhamento de duração na seção da tabela hg_query_log para obter detalhes sobre cada etapa.
SELECT status AS "Status",
duration AS "Duration (ms)",
optimization_cost AS "Optimization cost (ms)",
start_query_cost AS "Startup cost (ms)",
get_next_cost AS "Execution cost (ms)",
duration - optimization_cost - start_query_cost - get_next_cost AS "Other cost (ms)",
query_id AS "Query ID",
query::char(30)
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '10 min'
ORDER BY duration DESC,
start_query_cost DESC,
optimization_cost,
get_next_cost DESC,
duration - optimization_cost - start_query_cost - get_next_cost DESC
LIMIT 100;
Exemplo de saída:
Status | Duration (ms) | Optimization cost (ms) | Startup cost (ms) | Execution cost (ms) | Other cost (ms) | Query ID | query
---------+---------------+------------------------+-------------------+---------------------+-----------------+--------------------+--------------------------------
SUCCESS | 4572 | 521 | 320 | 3726 | 5 | 6000260625679xxxx | -- /* user: wang ip: xxx.xx.x
SUCCESS | 1490 | 538 | 98 | 846 | 8 | 12000250867886xxxx | -- /* user: lisa ip: xxx.xx.x
SUCCESS | 1230 | 502 | 95 | 625 | 8 | 26000512070295xxxx | -- /* user: zhang ip: xxx.xx.
(3 rows)
Visualizar volume de consultas e dados lidos por hora (últimas 3 horas):
SELECT date_trunc('hour', query_start) AS query_start,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
GROUP BY 1;
Comparar tráfego com a mesma janela ontem:
SELECT query_date,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '3 h'
GROUP BY query_date
UNION ALL
SELECT query_date,
count(1) AS query_count,
sum(read_bytes) AS read_bytes,
sum(cpu_time_ms) AS cpu_time_ms
FROM hologres.hg_query_log
WHERE query_start >= now() - interval '1d 3h'
AND query_start <= now() - interval '1d'
GROUP BY query_date;
Encontrar a primeira consulta com falha em uma janela de tempo:
SELECT status AS "Status",
regexp_replace(message, '\n', ' ')::char(150) AS "Error message",
duration AS "Duration (ms)",
query_start AS "Start time",
query_id AS "Query ID",
query::char(100) AS "Query"
FROM hologres.hg_query_log
WHERE query_start BETWEEN '2021-03-25 17:00:00'::timestamptz
AND '2021-03-25 17:42:00'::timestamptz + interval '2 min'
AND status = 'FAILED'
ORDER BY query_start ASC
LIMIT 100;
Exemplo de saída:
Status | Error message | Duration (ms) | Start time | Query ID | Query
--------+--------------------------------------------------------------+---------------+------------------------+--------------------+-------
FAILED | Query:[1070285448673xxxx] code: kActorInvokeError msg: "..." | 1460 | 2021-03-25 17:28:54+08 | 1070285448673xxxx | S...
FAILED | Query:[1016285560553xxxx] code: kActorInvokeError msg: "..." | 131 | 2021-03-25 17:28:55+08 | 1016285560553xxxx | S...
(2 rows)
Encontrar novos padrões de consulta de ontem (contagem total):
Consultas que aparecem pela primeira vez em comparação com anteontem, agrupadas por impressão digital.
SELECT COUNT(1)
FROM (
SELECT DISTINCT t1.digest
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND digest IS NOT NULL
) AS a;
Exemplo de saída — 10 novos padrões de consulta ontem:
count
-------
10
(1 row)
Encontrar novos padrões de consulta de ontem (por tipo):
SELECT a.command_tag,
COUNT(1)
FROM (
SELECT DISTINCT t1.digest, t1.command_tag
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a
GROUP BY 1
ORDER BY 2 DESC;
Exemplo de saída:
command_tag | count
-------------+-------
INSERT | 8
SELECT | 2
(2 rows)
Encontrar novos padrões de consulta de ontem (com detalhes):
SELECT a.usename, a.status, a.query_id, a.digest,
a.datname, a.command_tag, a.query, a.cpu_time_ms, a.memory_bytes
FROM (
SELECT DISTINCT
t1.usename, t1.status, t1.query_id, t1.digest,
t1.datname, t1.command_tag, t1.query, t1.cpu_time_ms, t1.memory_bytes
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a;
Encontrar novos padrões de consulta de ontem (por hora):
SELECT to_char(a.query_start, 'HH24') AS query_start_hour,
a.command_tag,
COUNT(1)
FROM (
SELECT DISTINCT t1.query_start, t1.digest, t1.command_tag
FROM hologres.hg_query_log t1
WHERE t1.query_start >= CURRENT_DATE - INTERVAL '1 day'
AND t1.query_start < CURRENT_DATE
AND NOT EXISTS (
SELECT 1
FROM hologres.hg_query_log t2
WHERE t2.digest = t1.digest
AND t2.query_start < CURRENT_DATE - INTERVAL '1 day'
)
AND t1.digest IS NOT NULL
) AS a
GROUP BY 1, 2
ORDER BY 3 DESC;
Exemplo de saída — às 21:00 ontem, 8 padrões INSERT; às 11:00 e 13:00, 1 padrão SELECT cada:
query_start_hour | command_tag | count
------------------+-------------+-------
21 | INSERT | 8
11 | SELECT | 1
13 | SELECT | 1
(3 rows)
Contar consultas lentas por impressão digital (ontem):
SELECT digest,
command_tag,
count(1)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '1 day'
AND query_start < CURRENT_DATE
GROUP BY 1, 2
ORDER BY 3 DESC;
Encontrar os 10 principais padrões de consulta com maior tempo médio de CPU (último dia):
SELECT digest,
avg(cpu_time_ms)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '1 day'
AND query_start < CURRENT_DATE
AND digest IS NOT NULL
AND usename != 'system'
AND cpu_time_ms IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;
Encontrar os 10 principais padrões de consulta com maior uso médio de memória (última semana):
SELECT digest,
avg(memory_bytes)
FROM hologres.hg_query_log
WHERE query_start >= CURRENT_DATE - INTERVAL '7 day'
AND query_start < CURRENT_DATE
AND digest IS NOT NULL
AND memory_bytes IS NOT NULL
GROUP BY 1
ORDER BY 2 DESC
LIMIT 10;
Parâmetros de configuração
Use estes parâmetros GUC para controlar o que é registrado e o nível de detalhe capturado.
log_min_duration_statement
Controla a duração mínima da consulta para registro em log.
Padrão: 100 ms (a partir da V2.2.7; versões anteriores têm padrão de 1.000 ms).
Valor mínimo: 100 ms.
Defina como
-1para desativar completamente o registro de consultas lentas.Apenas superusuários podem alterar isso no nível do banco de dados. Usuários regulares podem alterar no nível da sessão.
As alterações aplicam-se apenas a novas consultas.
-- Database level (superuser only)
ALTER DATABASE dbname SET log_min_duration_statement = '250ms';
-- Session level
SET log_min_duration_statement = '250ms';
log_min_duration_query_stats
Controla se as estatísticas de execução são capturadas para uma consulta.
Padrão: registra estatísticas para consultas com duração superior a 10 s.
Defina como
-1para desativar a coleta de estatísticas.Estatísticas consomem armazenamento significativo. Reduza este valor apenas para solução de problemas pontual; restaure-o depois.
As alterações aplicam-se apenas a novas consultas.
-- Database level (superuser only)
ALTER DATABASE dbname SET log_min_duration_query_stats = '20s';
-- Session level
SET log_min_duration_query_stats = '20s';
log_min_duration_query_plan
Controla se o plano de execução é capturado para uma consulta.
Padrão: registra planos para consultas com duração superior a 10 s.
Defina como
-1para desativar a captura de plano.Para solução de problemas ad hoc, use
EXPLAIN— ele retorna o plano instantaneamente sem registrar em log.As alterações aplicam-se apenas a novas consultas.
-- Database level (superuser only)
ALTER DATABASE dbname SET log_min_duration_query_plan = '10s';
-- Session level
SET log_min_duration_query_plan = '10s';
Modificar retenção de logs
A partir da V3.0.27, você pode alterar o período de retenção dos logs de consultas lentas no nível do banco de dados.
ALTER DATABASE <db_name> SET hg_query_log_retention_time_sec = 2592000;
|
Aspecto |
Detalhe |
|
Unidade |
Segundos |
|
Intervalo |
3–30 dias (259.200–2.592.000 segundos) |
|
Escopo |
Apenas novos logs (logs existentes mantêm sua retenção original) |
|
Aplica-se a |
Apenas novas conexões |
|
Limpeza |
Logs expirados são excluídos imediatamente, não assincronicamente |
Exportar logs de consultas lentas
Exporte dados de hg_query_log para uma tabela interna do Hologres, tabela externa do MaxCompute ou OSS para armazenamento de longo prazo ou análise.
Antes de exportar, observe:
A conta que executa o comando
INSERT INTO ... SELECT ... FROM hologres.hg_query_logdeve ter acesso ahg_query_log. Para exportações em toda a instância, são necessárias permissões de superusuário oupg_read_all_stats— caso contrário, os dados exportados estarão incompletos.query_starté uma coluna indexada. Sempre a inclua na sua cláusula WHERE para melhorar o desempenho e reduzir o uso de recursos.-
Não aplique funções a
query_startna cláusula WHERE — isso impede o uso do índice.-- Correct: use range conditions on query_start directly WHERE query_start >= '2022-08-03' AND query_start < '2022-08-04' -- Incorrect: wrapping query_start in a function bypasses the index WHERE to_char(query_start, 'yyyymmdd') = '20220101'
Exportar para uma tabela interna do Hologres
-- Step 1: Create the target table
CREATE TABLE query_log_download (
usename text,
status text,
query_id text,
datname text,
command_tag text,
duration integer,
message text,
query_start timestamp with time zone,
query_date text,
query text,
result_rows bigint,
result_bytes bigint,
read_rows bigint,
read_bytes bigint,
affected_rows bigint,
affected_bytes bigint,
memory_bytes bigint,
shuffle_bytes bigint,
cpu_time_ms bigint,
physical_reads bigint,
pid integer,
application_name text,
engine_type text[],
client_addr text,
table_write text,
table_read text[],
session_id text,
session_start timestamp with time zone,
trans_id text,
command_id text,
optimization_cost integer,
start_query_cost integer,
get_next_cost integer,
extended_cost text,
plan text,
statistics text,
visualization_info text,
query_detail text,
query_extinfo text[]
);
-- Step 2: Export logs for a specific date
INSERT INTO query_log_download
SELECT
usename, status, query_id, datname, command_tag, duration, message,
query_start, query_date, query, result_rows, result_bytes, read_rows,
read_bytes, affected_rows, affected_bytes, memory_bytes, shuffle_bytes,
cpu_time_ms, physical_reads, pid, application_name, engine_type,
client_addr, table_write, table_read, session_id, session_start,
trans_id, command_id, optimization_cost, start_query_cost, get_next_cost,
extended_cost, plan, statistics, visualization_info, query_detail, query_extinfo
FROM hologres.hg_query_log
WHERE query_start >= '2022-08-03'
AND query_start < '2022-08-04';
Exportar para uma tabela externa do MaxCompute
-
No MaxCompute, crie uma tabela particionada para receber os dados:
CREATE TABLE IF NOT EXISTS mc_holo_query_log ( username STRING COMMENT 'The username for the query', status STRING COMMENT 'The final status of the query: success or failed', query_id STRING COMMENT 'The query ID', datname STRING COMMENT 'The name of the database for the query', command_tag STRING COMMENT 'The type of query', duration BIGINT COMMENT 'The query duration in milliseconds (ms)', message STRING COMMENT 'The error message', query STRING COMMENT 'The text content of the query', read_rows BIGINT COMMENT 'The number of rows read by the query', read_bytes BIGINT COMMENT 'The number of bytes read by the query', memory_bytes BIGINT COMMENT 'The peak memory consumption on a single node (not exact)', shuffle_bytes BIGINT COMMENT 'The estimated number of bytes for data shuffle (not exact)', cpu_time_ms BIGINT COMMENT 'The total CPU time in milliseconds (not exact)', physical_reads BIGINT COMMENT 'The number of physical reads', application_name STRING COMMENT 'The query application type', engine_type ARRAY<STRING> COMMENT 'The engine used for the query', table_write STRING COMMENT 'The table to which the SQL statement writes data', table_read ARRAY<STRING> COMMENT 'The table from which the SQL statement reads data', plan STRING COMMENT 'The execution plan for the query', optimization_cost BIGINT COMMENT 'The time to generate the query execution plan', start_query_cost BIGINT COMMENT 'The query startup time', get_next_cost BIGINT COMMENT 'The query execution duration', extended_cost STRING COMMENT 'Other detailed costs of the query', query_detail STRING COMMENT 'Other extended information about the query (JSON format)', query_extinfo ARRAY<STRING> COMMENT 'Other extended information about the query (ARRAY format)', query_start STRING COMMENT 'The query start time', query_date STRING COMMENT 'The query start date' ) COMMENT 'Hologres instance query log' PARTITIONED BY (ds STRING COMMENT 'stat date') LIFECYCLE 365; ALTER TABLE mc_holo_query_log ADD PARTITION (ds=20220803); -
No Hologres, importe a tabela do MaxCompute como uma tabela externa e exporte os logs:
IMPORT FOREIGN SCHEMA project_name LIMIT TO (mc_holo_query_log) FROM SERVER odps_server INTO public; INSERT INTO mc_holo_query_log SELECT usename AS username, status, query_id, datname, command_tag, duration, message, query, read_rows, read_bytes, memory_bytes, shuffle_bytes, cpu_time_ms, physical_reads, application_name, engine_type, table_write, table_read, plan, optimization_cost, start_query_cost, get_next_cost, extended_cost, query_detail, query_extinfo, query_start, query_date, '20220803' FROM hologres.hg_query_log WHERE query_start >= '2022-08-03' AND query_start < '2022-08-04';
FAQ
Linhas retornadas e linhas lidas da consulta estão ausentes no Hologres V1.1.
Isso ocorre porque a coleta de logs de consultas lentas está incompleta nas versões V1.1 afetadas. Nas versões V1.1.36 a V1.1.49, ative o seguinte parâmetro GUC para coletar estatísticas completas:
-- Database level (recommended — set once per database)
ALTER DATABASE <db_name> SET hg_experimental_force_sync_collect_execution_statistics = ON;
-- Session level
SET hg_experimental_force_sync_collect_execution_statistics = ON;
Substitua <db_name> pelo nome do seu banco de dados.
Se sua instância for anterior à V1.1.36, consulte Erros comuns de preparação de atualização ou entre em contato com o suporte do Hologres. Para mais informações, consulte Como obter mais suporte online? .
Esse comportamento é resolvido por padrão na V1.1.49 e posteriores.
A duração nos logs de consultas lentas inclui o tempo de Busca (Fetching)?
Não. O campo duration nos logs de consultas lentas do Hologres mede apenas o tempo de execução no lado do servidor, que consiste em geração de plano (optimization_cost), inicialização (start_query_cost) e computação (get_next_cost). Ele não inclui o tempo que o cliente gasta buscando dados de resultado (a fase Fetching).
Se consultas de uma ferramenta de BI como o Quick BI levarem significativamente mais tempo do que a mesma instrução SQL executada no HoloWeb ou na linha de comando, as causas comuns são:
A ferramenta de BI envia várias consultas simultaneamente, o que aumenta o tempo geral de resposta sob alto paralelismo.
O campo
get_next_costinclui o tempo de transferência de rede para enviar dados de resultado do servidor para o cliente. Um valor alto deget_next_costpode refletir latência na recuperação de dados no lado do cliente, em vez de computação lenta no lado do servidor.
Para distinguir entre atrasos no lado do servidor e no lado do cliente, execute a consulta com EXPLAIN ANALYZE e examine o campo get_next_cost. Um get_next_cost alto combinado com optimization_cost e start_query_cost baixos geralmente indica que o tempo é gasto na transferência de dados, e não na execução da consulta.
Próximos passos
Para monitorar e gerenciar consultas ativas em sua instância, consulte Gerenciar consultas.