Como un breve suplemento al artículo
Intente crear un análogo de ASH para PostgreSQL .
Desafío
Debe vincular el historial de vistas pg_stat_statemenets, pg_stat_activity. Como resultado, al usar el historial de planes de ejecución de la tabla de servicio log_query, puede obtener mucha información útil para resolver incidentes de rendimiento y optimizar consultas.
Advertencia
Debido a la novedad del tema y al período de prueba incompleto, el artículo puede contener errores. Las críticas y los comentarios son fuertemente alentados y esperados.
Datos de entrada
Tabla History_pg_stat_activity Tabla Pg_stat_db_queries CREATE TABLE pg_stat_db_queries ( database_id integer , queryid bigint , query text , max_time double precision );(
Vista 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;
Tabla 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 general
Actualizar tabla pg_stat_db_queries
Actualizar vista 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;
Rellenar la tabla 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, la tabla contiene textos de consulta normalizados, queryid, el tiempo máximo de ejecución de la consulta en el momento actual (utilizado para la supervisión).
Llenar log_query y formar un historial de planes de ejecución.
El texto de la solicitud real se toma del archivo de registro. Archivo de registro del host de destino al host de supervisión en partes, bash script, cron. Para ahorrar espacio y debido a la trivialidad de la tarea de copiar una parte de un archivo de texto de host a host, no se proporciona el script.
Analizar un archivo de registro y extraer texto de consulta Log_query relleno de tabla Como resultado, la tabla contiene el texto de solicitud real, los planes de ejecución, el valor hash del plan de ejecución, el valor hash del texto de solicitud.
Complete el valor de queryid en la tabla history_pg_stat_activity
update_history_pg_stat_activity_by_queryid.sql Como resultado, la tabla contiene el valor de queryid correspondiente al valor de queryid de la consulta.
Resumen
Al vincular pg_stat_activity, pg_stat_statements, log_query, puede obtener mucha información útil sobre la solicitud, en particular:
- Historia de los planes de implementación.
- Historial de solicitud de tiempo de CPU.
- Solicitar historial de espera.
Los datos y muchos informes adicionales se describirán en el próximo artículo.
Desarrollo
Al vincular la información disponible con el historial de la vista pg_locks, puede obtener información sobre qué bloqueos específicos estaba esperando la solicitud y, lo más importante, qué proceso (solicitud) mantenía este bloqueo.
La solución a este problema se describirá en el próximo artículo. Ahora las pruebas y el refinamiento están en marcha.