Como um pequeno complemento ao artigo
Tentativa de criar um análogo de ASH para o PostgreSQL .
Desafio
Você precisa vincular o histórico de exibição pg_stat_statemenets, pg_stat_activity. Como resultado, usando o histórico de planos de execução da tabela de serviço log_query, você pode obter muitas informações úteis para resolver problemas de desempenho e otimizar consultas.
Advertência
Devido à novidade do tópico e ao período de teste incompleto, o artigo pode conter erros. Críticas e comentários são fortemente incentivados e esperados.
Dados de entrada
Tabela History_pg_stat_activity Tabela Pg_stat_db_queries CREATE TABLE pg_stat_db_queries ( database_id integer , queryid bigint , query text , max_time double precision );(
Visualização materializada de mvw_pg_stat_queries CREATE MATERIALIZED VIEW public.mvw_pg_stat_queries AS SELECT t.queryid, t.max_time, t.query FROM public.dblink('LINK1'::text, 'SELECT queryid , max_time , query FROM pg_stat_statements WHERE dbid=(SELECT oid FROM pg_database WHERE datname=current_database() ) AND max_time >= 0 '::text) t(queryid bigint, max_time double precision, query text) WITH NO DATA;
Tabela Log_query CREATE TABLE log_query ( id integer , queryid bigint , query_md5hash text , database_id integer , timepoint timestamp without time zone , query text , explained_plan text[] , plan_md5hash text , explained_plan_wo_costs text[] , plan_hash_value text , ip text, port text , pid integer );
Algoritmo geral
Atualizar tabela pg_stat_db_queries
Atualizar exibição de material mvw_pg_stat_queries CREATE OR REPLACE FUNCTION refresh_pg_stat_queries_list( database_id int) RETURNS BOOLEAN AS $$ DECLARE result BOOLEAN ; database_rec record ; BEGIN SELECT * INTO database_rec FROM endpoint e JOIN database d ON e.id = d.endpoint_id WHERE d.id = database_id ; IF NOT database_rec.is_need_monitoring THEN RAISE NOTICE 'NO NEED MONITORING FOR database_id=%',database_id; return TRUE ; END IF ; EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||database_rec.host||' port=5432 dbname='||database_rec.name|| ' user='||database_rec.s_name||' password='||database_rec.s_pass|| ' '')'; REFRESH MATERIALIZED VIEW mvw_pg_stat_queries ; PERFORM dblink_disconnect('LINK1'); RETURN result; END $$ LANGUAGE plpgsql;
Preencher tabela pg_stat_db_queries CREATE OR REPLACE FUNCTION refresh_pg_stat_db_queries( ) RETURNS BOOLEAN AS $$ DECLARE result BOOLEAN ; database_rec record ; pg_stat_rec record ; BEGIN TRUNCATE pg_stat_db_queries; FOR database_rec IN SELECT * FROM database d LOOP IF NOT database_rec.is_need_monitoring THEN RAISE NOTICE 'NO NEED MONITORING FOR database_id=%',database_rec.id; CONTINUE ; END IF ; PERFORM refresh_pg_stat_queries_list( database_rec.id ) ; FOR pg_stat_rec IN SELECT * FROM mvw_pg_stat_queries LOOP INSERT INTO pg_stat_db_queries ( database_id , queryid , query , max_time ) VALUES ( database_rec.id , pg_stat_rec.queryid , pg_stat_rec.query , pg_stat_rec.max_time); END LOOP; END LOOP; RETURN TRUE; END $$ LANGUAGE plpgsql;
Como resultado, a tabela contém textos de consulta normalizados, queryid, o tempo máximo de execução da consulta no momento atual (usado para monitoramento).
Preenchendo log_query e formando um histórico de planos de execução.
O texto real da solicitação é obtido do arquivo de log. Arquivo de log do host de destino para o host de monitoramento em partes, script bash, cron. Para economizar espaço e devido à trivialidade da tarefa de copiar uma parte de um arquivo de texto de host para host, o script não é fornecido.
Analisando um Arquivo de Log e Extraindo Texto de Consulta Preenchimento da tabela Log_query Como resultado, a tabela contém o texto da solicitação real, planos de execução, valor do hash do plano de execução, valor do hash do texto da solicitação.
Preencha o valor da queryid na tabela history_pg_stat_activity
update_history_pg_stat_activity_by_queryid.sql Como resultado, a tabela contém o valor de queryid correspondente ao valor de queryid da consulta.
Sumário
Ao vincular pg_stat_activity, pg_stat_statements, log_query, você pode obter muitas informações úteis sobre a solicitação, em particular:
- Histórico dos planos de implementação.
- Histórico da solicitação de tempo da CPU.
- Solicitar histórico de espera.
Dados e muitos relatórios adicionais serão descritos no próximo artigo.
Desenvolvimento
Ao vincular as informações disponíveis ao histórico da visualização pg_locks, é possível obter informações sobre quais bloqueios específicos a solicitação estava aguardando e, o mais importante, qual processo (solicitação) estava mantendo esse bloqueio.
A solução para esse problema será descrita no próximo artigo. Agora, o teste e o refinamento estão em andamento.