Pagsubaybay sa pagganap ng mga query sa PostgreSQL. Bahagi 1 - pag-uulat

Engineer - isinalin mula sa Latin - inspirasyon.
Ang isang engineer ay maaaring gumawa ng kahit ano. (c) R. Diesel.
Mga Epigraph.
Pagsubaybay sa pagganap ng mga query sa PostgreSQL. Bahagi 1 - pag-uulat
O isang kuwento tungkol sa kung bakit kailangang alalahanin ng isang database administrator ang kanyang nakaraan sa programming.

paunang salita

Lahat ng pangalan ay pinalitan. Ang mga pagkakataon ay random. Ang materyal ay kumakatawan lamang sa personal na opinyon ng may-akda.

Disclaimer ng mga warranty: Ang nakaplanong serye ng mga artikulo ay hindi naglalaman ng isang detalyado at tumpak na paglalarawan ng mga talahanayan at mga script na ginamit. Ang mga materyales ay hindi maaaring gamitin kaagad "AS IS".
Una, dahil sa malaking dami ng materyal,
pangalawa, dahil sa malapit na relasyon sa production base ng isang tunay na customer.
Samakatuwid, ang mga artikulo ay maglalaman lamang ng mga ideya at paglalarawan sa pinaka-pangkalahatang anyo.
Marahil sa hinaharap ang sistema ay lalago sa antas ng pag-post sa GitHub, o maaaring hindi. Magpapakita ang oras.

Ang simula ng kwento-"Naaalala mo ba kung paano nagsimula ang lahat'.
Ano ang nangyari bilang isang resulta, sa pinaka-pangkalahatang mga termino - "Synthesis bilang isa sa mga pamamaraan para sa pagpapabuti ng pagganap ng PostgreSQL»

Bakit kailangan ko ang lahat ng ito?

Buweno, una, upang hindi makalimutan, alalahanin ang maluwalhating mga araw sa pagreretiro.
Pangalawa, para ma-systematize ang nakasulat. Dahil minsan nalilito ako at nakakalimutan ko ang ilang bahagi.

Buweno, at ang pinakamahalagang bagay ay maaaring magamit ito para sa isang tao at tulungan silang maiwasan ang muling pag-imbento ng gulong at hindi pagkolekta ng rake. Sa madaling salita, pagbutihin ang iyong karma (hindi ang kay Khabrov). Dahil ang pinakamahalagang bagay sa mundong ito ay mga ideya. Ang pangunahing bagay ay upang makahanap ng isang ideya. Ngunit ang paggawa ng isang ideya sa katotohanan ay isang purong teknikal na tanong.

Kaya, simulan natin, unti-unti...

Pagbubuo ng problema.

Available:

PostgreSQL(10.5) database, mixed load type (OLTP+DSS), medium-light load, na matatagpuan sa AWS cloud.
Walang pagsubaybay sa database; ibinibigay ang pagsubaybay sa imprastraktura sa anyo ng mga karaniwang tool ng AWS sa isang minimal na pagsasaayos.

Ito ay kinakailangan:

Subaybayan ang pagganap at katayuan ng database, maghanap at magkaroon ng paunang impormasyon para sa pag-optimize ng mabibigat na query sa database.

Maikling panimula o pagsusuri ng mga opsyon sa solusyon

Upang magsimula, subukan nating pag-aralan ang mga opsyon para sa paglutas ng problema mula sa punto ng view ng isang paghahambing na pagsusuri ng mga benepisyo at disadvantages para sa engineer, at hayaan ang mga may karapatan sa staffing na makitungo sa mga benepisyo at pagkalugi ng pamamahala.

Opsyon 1 - "Paggawa on demand"

Iniiwan namin ang lahat ng kung ano. Kung ang customer ay hindi nasiyahan sa isang bagay sa pag-andar, pagganap ng database o application, aabisuhan niya ang mga inhinyero ng DBA sa pamamagitan ng e-mail o sa pamamagitan ng paglikha ng isang insidente sa tray ng tiket.
Ang engineer, na natanggap ang abiso, ay mauunawaan ang problema, mag-aalok ng solusyon o ilagay ang problema sa back burner, umaasa na ang lahat ay malulutas mismo, at gayon pa man, ang lahat ay malapit nang makalimutan.
Gingerbread at mga donut, mga pasa at mga bukolGingerbread at donut:
1. Hindi na kailangang gumawa ng anumang dagdag.
2. Palaging may pagkakataon na gumawa ng mga dahilan at siraan.
3. Maraming oras na maaari mong gugulin sa iyong sariling paghuhusga.
Mga pasa at bukol:
1. Maaga o huli, iisipin ng customer ang kakanyahan ng pag-iral at unibersal na hustisya sa mundong ito at muli niyang tanungin ang kanyang sarili - bakit ko binabayaran ang aking pera? Ang kahihinatnan ay palaging pareho - ang tanging tanong ay kapag ang customer ay magsasawa at magpaalam. At ang feeder ay walang laman. Ito ay malungkot.
2. Pag-unlad ng inhinyero - zero.
3. Mga kahirapan sa pagpaplano ng trabaho at pagkarga

Opsyon 2- “Pagsasayaw gamit ang mga tamburin, pagpapasingaw at pagsusuot ng sapatos”

Talata 1-Bakit kailangan natin ng sistema ng pagsubaybay, matatanggap natin ang lahat na may mga kahilingan. Nagpapatakbo kami ng isang grupo ng lahat ng uri ng mga query sa diksyunaryo ng data at mga dynamic na view, i-on ang lahat ng uri ng mga counter, ilagay ang lahat sa mga talahanayan, at pana-panahong sinusuri ang mga listahan at talahanayan. Bilang resulta, mayroon kaming maganda o hindi napakagandang mga graph, talahanayan, ulat. Ang pangunahing bagay ay magkaroon ng higit pa, higit pa.
Talata 2-Bumubuo kami ng aktibidad at inilunsad ang pagsusuri ng lahat ng ito.
Talata 3-Naghahanda kami ng isang tiyak na dokumento, ang tawag namin sa dokumentong ito ay simple - "paano kami dapat mag-set up ng isang database."
Talata 4-Ang customer, na nakikita ang lahat ng kagandahang ito ng mga graph at numero, ay nasa isang bata, walang muwang na kumpiyansa - ngayon ang lahat ay gagana para sa amin, sa lalong madaling panahon. At, madali at walang sakit na ibinabahagi niya ang kanyang mga mapagkukunang pinansyal. Kumpiyansa din ang management na gumagana nang mahusay ang aming mga inhinyero. Naglo-load sa maximum.
Talata 5-Ulitin ang Hakbang 1 nang regular.
Gingerbread at mga donut, mga pasa at mga bukolGingerbread at donut:
1. Ang buhay ng mga manager at engineer ay simple, predictable at puno ng aktibidad. Lahat ay buzz, lahat ay abala.
2. Hindi rin masama ang buhay ng customer - lagi siyang sigurado na kailangan lang niyang maging matiyaga at magiging maayos ang lahat. Hindi ito nagiging mas mahusay, mabuti, ang mundo ay hindi patas, sa susunod na buhay ay masuwerte ka.
Mga pasa at bukol:
1. Maaga o huli, magkakaroon ng mas mabilis na provider ng katulad na serbisyo na gagawa ng parehong bagay, ngunit mas mura ng kaunti. At kung pareho ang resulta, bakit magbayad ng higit pa. Na muling hahantong sa pagkawala ng feeder.
2. Nakakatamad. Gaano kabagot ang anumang walang kabuluhang aktibidad.
3. Tulad ng sa nakaraang bersyon, walang pag-unlad. Ngunit para sa isang inhinyero, ang downside ay na, hindi tulad ng unang opsyon, kailangan mong patuloy na bumuo ng isang IBD. At ito ay nangangailangan ng oras. Na maaari mong gastusin para sa kapakanan ng iyong minamahal. Dahil hindi mo kayang alagaan ang iyong sarili, walang sinuman ang nagbibigay ng masama sa iyo.

Opsyon 3 - Hindi mo kailangang mag-imbento ng bisikleta, kailangan mo lang itong bilhin at sumakay.

Ito ay hindi para sa wala na ang mga inhinyero mula sa ibang mga kumpanya ay kumakain ng pizza na may beer (oh, ang mga araw ng kaluwalhatian ng St. Petersburg noong 90s). Gamitin natin ang mga sistema ng pagsubaybay na ginawa, na-debug at gumagana, at sa pangkalahatan ay pakinabang (mabuti, hindi bababa sa kanilang mga tagalikha).
Gingerbread at mga donut, mga pasa at mga bukolGingerbread at donut:
1. Hindi na kailangang mag-aksaya ng oras sa pagbuo ng isang bagay na naimbento na. Kunin mo at gamitin mo.
2. Ang mga sistema ng pagsubaybay ay hindi isinulat ng mga mangmang at sila ay, siyempre, kapaki-pakinabang.
3. Ang mga gumaganang sistema ng pagsubaybay ay karaniwang nagbibigay ng kapaki-pakinabang na na-filter na impormasyon.
Mga pasa at bukol:
1. Ang engineer sa kasong ito ay hindi isang engineer, ngunit isang user lang ng produkto ng ibang tao. O isang user.
2. Ang customer ay dapat na kumbinsido sa pangangailangan na bumili ng isang bagay na, sa pangkalahatan, hindi niya nais na maunawaan, at hindi dapat, at sa pangkalahatan ang badyet para sa taon ay naaprubahan at hindi magbabago. Pagkatapos ay kailangan mong maglaan ng isang hiwalay na mapagkukunan at i-configure ito para sa isang tiyak na sistema. Yung. kailangan mo munang magbayad, magbayad at magbayad muli. At kuripot ang customer. Ito ang pamantayan ng buhay na ito.

Ano ang gagawin - Chernyshevsky? Napaka-pertinent ng tanong mo. (Kasama)

Sa partikular na kaso at sa kasalukuyang sitwasyon, magagawa mo ito nang medyo naiiba - gumawa tayo ng sarili nating monitoring system.
Pagsubaybay sa pagganap ng mga query sa PostgreSQL. Bahagi 1 - pag-uulat
Well, hindi isang sistema, siyempre, sa buong kahulugan ng salita, iyon ay masyadong malakas at mapangahas, ngunit kahit papaano ay ginagawang mas madali ang iyong gawain at mangolekta ng higit pang impormasyon upang malutas ang mga insidente ng pagganap. Upang hindi mahanap ang iyong sarili sa isang sitwasyon - "pumunta doon, hindi ko alam kung saan, maghanap ng isang bagay, hindi ko alam kung ano."

Ano ang mga kalamangan at kahinaan ng pagpipiliang ito:

Pros:
1. Ito ay kawili-wili. Well, hindi bababa sa ito ay mas kawili-wili kaysa sa patuloy na "pag-urong ng datafile, baguhin ang tablespace, atbp."
2. Ito ay mga bagong kasanayan at bagong pag-unlad. Na, maaga o huli, ay magbibigay sa iyo ng karapat-dapat na gingerbread at donut.
Cons:
1. Kailangan mong magtrabaho. Magsikap.
2. Kailangan mong regular na ipaliwanag ang kahulugan at mga prospect ng lahat ng aktibidad.
3. May isang bagay na kailangang isakripisyo, dahil ang tanging mapagkukunan na magagamit ng isang inhinyero - oras - ay limitado ng Uniberso.
4. Ang pinakamasama at pinaka-hindi kasiya-siyang bagay - ang resulta ay maaaring kalokohan tulad ng "Hindi isang daga, hindi isang palaka, ngunit isang hindi kilalang hayop."

Ang mga hindi nakikipagsapalaran ay hindi umiinom ng champagne.
Kaya - ang saya ay nagsisimula.

Pangkalahatang ideya - eskematiko

Pagsubaybay sa pagganap ng mga query sa PostgreSQL. Bahagi 1 - pag-uulat
(Ilustrasyon na kinuha mula sa artikulo «Synthesis bilang isa sa mga pamamaraan para sa pagpapabuti ng pagganap ng PostgreSQL")

Paliwanag:

  • Ang karaniwang extension ng PostgreSQL na "pg_stat_statements" ay naka-install sa target na database.
  • Sa database ng pagsubaybay, lumikha kami ng isang set ng mga talahanayan ng serbisyo para sa pag-iimbak ng kasaysayan ng pg_stat_statements sa paunang yugto at para sa pag-set up ng mga sukatan at pagsubaybay sa hinaharap
  • Sa monitoring host, gumagawa kami ng set ng mga script ng bash, kasama ang mga para sa pagbuo ng mga insidente sa ticket system.

Mga talahanayan ng serbisyo

Una, isang eskematiko na pinasimple na ERD, kung ano ang nangyari sa dulo:
Pagsubaybay sa pagganap ng mga query sa PostgreSQL. Bahagi 1 - pag-uulat
Maikling paglalarawan ng mga talahanayanendpoint — host, punto ng koneksyon sa instance
database - mga parameter ng database
pg_stat_history - isang makasaysayang talahanayan para sa pag-iimbak ng mga pansamantalang snapshot ng pg_stat_statements view ng target na database
metric_glossary - diksyunaryo ng mga sukatan ng pagganap
metric_config — pagsasaayos ng mga indibidwal na sukatan
sukatan — isang partikular na sukatan para sa kahilingan na sinusubaybayan
metric_alert_history - kasaysayan ng mga babala sa pagganap
log_query — isang talahanayan ng serbisyo para sa pag-iimbak ng mga na-parse na tala mula sa isang PostgreSQL log file na na-download mula sa AWS
baseline — mga parameter ng mga yugto ng panahon na ginamit bilang batayan
checkpoint — pagsasaayos ng mga sukatan para sa pagsuri sa katayuan ng database
checkpoint_alert_history — kasaysayan ng babala ng mga sukatan ng pagsusuri sa kalusugan ng database
pg_stat_db_queries — talahanayan ng serbisyo ng mga aktibong kahilingan
activity_log — talahanayan ng serbisyo ng log ng aktibidad
trap_oid — talahanayan ng serbisyo sa pagsasaayos ng bitag

Stage 1 - mangolekta ng istatistikal na impormasyon tungkol sa pagganap at tumanggap ng mga ulat

Ang isang talahanayan ay ginagamit upang mag-imbak ng istatistikal na impormasyon pg_stat_history
pg_stat_history istraktura ng talahanayan

                                          Table "public.pg_stat_history" Column | Uri | Mga Modifier---------------------+------------------------- - -+------------------------------------------ id | integer | hindi null default nextval('pg_stat_history_id_seq'::regclass) snapshot_timestamp | timestamp na walang time zone | database_id | integer | dbid | oid | userid | oid | queryid | bigint | tanong | text | mga tawag | bigint | kabuuang_oras | dobleng katumpakan | min_time | dobleng katumpakan | max_time | dobleng katumpakan | mean_time | dobleng katumpakan | stddev_time | dobleng katumpakan | mga hilera | bigint | shared_blks_hit | bigint | shared_blks_read | bigint | shared_blks_dirtied | bigint | shared_blks_written | bigint | local_blks_hit | bigint | local_blks_read | bigint | local_blks_dirtied | bigint | local_blks_written | bigint | temp_blks_read | bigint | temp_blks_written | bigint | blk_read_time | dobleng katumpakan | blk_write_time | dobleng katumpakan | baseline_id | integer | Mga index: "pg_stat_history_pkey" PANGUNAHING KEY, btree (id) "database_idx" btree (database_id) "queryid_idx" btree (queryid) "snapshot_timestamp_idx" btree (snapshot_timestamp) Foreign-key na mga hadlang: (Yfdatabase_idxID) ) SA DELETE CASCADE

Gaya ng nakikita mo, ang talahanayan ay ang pinagsama-samang data ng view pg_stat_statements sa target na database.

Ang paggamit ng talahanayan na ito ay napaka-simple

pg_stat_history ay kumakatawan sa mga naipon na istatistika ng pagsasagawa ng query para sa bawat oras. Sa simula ng bawat oras, pagkatapos punan ang talahanayan, mga istatistika pg_stat_statements i-reset gamit ang pg_stat_statements_reset().
Tandaan: Kinokolekta ang mga istatistika para sa mga query na may tagal ng pagpapatupad na higit sa 1 segundo.
Populating ang pg_stat_history table

--pg_stat_history.sql
CREATE OR REPLACE FUNCTION pg_stat_history( ) RETURNS boolean AS $$
DECLARE
  endpoint_rec record ;
  database_rec record ;
  pg_stat_snapshot record ;
  current_snapshot_timestamp timestamp without time zone;
BEGIN
  current_snapshot_timestamp = date_trunc('minute',now());  
  
  FOR endpoint_rec IN SELECT * FROM endpoint 
  LOOP
    FOR database_rec IN SELECT * FROM database WHERE endpoint_id = endpoint_rec.id 
	  LOOP
	    
		RAISE NOTICE 'NEW SHAPSHOT IS CREATING';
		
		--Connect to the target DB	  
	    EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||endpoint_rec.host||' dbname='||database_rec.name||' user=USER password=PASSWORD '')';
 
        RAISE NOTICE 'host % and dbname % ',endpoint_rec.host,database_rec.name;
		RAISE NOTICE 'Creating snapshot of pg_stat_statements for database %',database_rec.name;
		
		SELECT 
	      *
		INTO 
		  pg_stat_snapshot
	    FROM dblink('LINK1',
	      'SELECT 
	       dbid , SUM(calls),SUM(total_time),SUM(rows) ,SUM(shared_blks_hit) ,SUM(shared_blks_read) ,SUM(shared_blks_dirtied) ,SUM(shared_blks_written) , 
           SUM(local_blks_hit) , SUM(local_blks_read) , SUM(local_blks_dirtied) , SUM(local_blks_written) , SUM(temp_blks_read) , SUM(temp_blks_written) , SUM(blk_read_time) , SUM(blk_write_time)
	       FROM pg_stat_statements WHERE dbid=(SELECT oid from pg_database where datname=current_database() ) 
		   GROUP BY dbid
  	      '
	               )
	      AS t
	       ( dbid oid , calls bigint , 
  	         total_time double precision , 
	         rows bigint , shared_blks_hit bigint , shared_blks_read bigint ,shared_blks_dirtied bigint ,shared_blks_written	 bigint ,
             local_blks_hit	 bigint ,local_blks_read bigint , local_blks_dirtied bigint ,local_blks_written bigint ,
             temp_blks_read	 bigint ,temp_blks_written bigint ,
             blk_read_time double precision , blk_write_time double precision	  
	       );
		 
		INSERT INTO pg_stat_history
          ( 
		    snapshot_timestamp  ,database_id  ,
			dbid , calls  ,total_time ,
            rows ,shared_blks_hit  ,shared_blks_read  ,shared_blks_dirtied  ,shared_blks_written ,local_blks_hit , 	 	
            local_blks_read,local_blks_dirtied,local_blks_written,temp_blks_read,temp_blks_written, 	
            blk_read_time, blk_write_time 
		  )		  
	    VALUES
	      (
	       current_snapshot_timestamp ,
		   database_rec.id ,
	       pg_stat_snapshot.dbid ,pg_stat_snapshot.calls,
	       pg_stat_snapshot.total_time,
	       pg_stat_snapshot.rows ,pg_stat_snapshot.shared_blks_hit ,pg_stat_snapshot.shared_blks_read ,pg_stat_snapshot.shared_blks_dirtied ,pg_stat_snapshot.shared_blks_written , 
           pg_stat_snapshot.local_blks_hit , pg_stat_snapshot.local_blks_read , pg_stat_snapshot.local_blks_dirtied , pg_stat_snapshot.local_blks_written , 
	       pg_stat_snapshot.temp_blks_read , pg_stat_snapshot.temp_blks_written , pg_stat_snapshot.blk_read_time , pg_stat_snapshot.blk_write_time 	   
	      );		   
		  
        RAISE NOTICE 'Creating snapshot of pg_stat_statements for queries with min_time more than 1000ms';
	
        FOR pg_stat_snapshot IN
          --All queries with max_time greater than 1000 ms
	      SELECT 
	        *
	      FROM dblink('LINK1',
	        'SELECT 
	         dbid , userid ,queryid,query,calls,total_time,min_time ,max_time,mean_time, stddev_time ,rows ,shared_blks_hit ,
			 shared_blks_read ,shared_blks_dirtied ,shared_blks_written , 
             local_blks_hit , local_blks_read , local_blks_dirtied , 
			 local_blks_written , temp_blks_read , temp_blks_written , blk_read_time , 
			 blk_write_time
	         FROM pg_stat_statements 
			 WHERE dbid=(SELECT oid from pg_database where datname=current_database() AND min_time >= 1000 ) 
  	        '

	                  )
	        AS t
	         ( dbid oid , userid oid , queryid bigint ,query text , calls bigint , 
  	           total_time double precision ,min_time double precision	 ,max_time double precision	 , mean_time double precision	 ,  stddev_time double precision	 , 
	           rows bigint , shared_blks_hit bigint , shared_blks_read bigint ,shared_blks_dirtied bigint ,shared_blks_written	 bigint ,
               local_blks_hit	 bigint ,local_blks_read bigint , local_blks_dirtied bigint ,local_blks_written bigint ,
               temp_blks_read	 bigint ,temp_blks_written bigint ,
               blk_read_time double precision , blk_write_time double precision	  
	         )
	    LOOP
		  INSERT INTO pg_stat_history
          ( 
		    snapshot_timestamp  ,database_id  ,
			dbid ,userid  , queryid  , query  , calls  ,total_time ,min_time ,max_time ,mean_time ,stddev_time ,
            rows ,shared_blks_hit  ,shared_blks_read  ,shared_blks_dirtied  ,shared_blks_written ,local_blks_hit , 	 	
            local_blks_read,local_blks_dirtied,local_blks_written,temp_blks_read,temp_blks_written, 	
            blk_read_time, blk_write_time 
		  )		  
	      VALUES
	      (
	       current_snapshot_timestamp ,
		   database_rec.id ,
	       pg_stat_snapshot.dbid ,pg_stat_snapshot.userid ,pg_stat_snapshot.queryid,pg_stat_snapshot.query,pg_stat_snapshot.calls,
	       pg_stat_snapshot.total_time,pg_stat_snapshot.min_time ,pg_stat_snapshot.max_time,pg_stat_snapshot.mean_time, pg_stat_snapshot.stddev_time ,
	       pg_stat_snapshot.rows ,pg_stat_snapshot.shared_blks_hit ,pg_stat_snapshot.shared_blks_read ,pg_stat_snapshot.shared_blks_dirtied ,pg_stat_snapshot.shared_blks_written , 
           pg_stat_snapshot.local_blks_hit , pg_stat_snapshot.local_blks_read , pg_stat_snapshot.local_blks_dirtied , pg_stat_snapshot.local_blks_written , 
	       pg_stat_snapshot.temp_blks_read , pg_stat_snapshot.temp_blks_written , pg_stat_snapshot.blk_read_time , pg_stat_snapshot.blk_write_time 	   
	      );
		  
        END LOOP;

        PERFORM dblink_disconnect('LINK1');  
				
	  END LOOP ;--FOR database_rec IN SELECT * FROM database WHERE endpoint_id = endpoint_rec.id 
    
  END LOOP;

RETURN TRUE;  
END
$$ LANGUAGE plpgsql;

Bilang isang resulta, pagkatapos ng ilang tagal ng panahon sa talahanayan pg_stat_history magkakaroon tayo ng isang set ng mga snapshot ng mga nilalaman ng talahanayan pg_stat_statements target na database.

Talagang nag-uulat

Gamit ang mga simpleng query, maaari kang makakuha ng lubos na kapaki-pakinabang at kawili-wiling mga ulat.

Pinagsama-samang data para sa isang partikular na yugto ng panahon

Humiling

SELECT 
  database_id , 
  SUM(calls) AS calls ,SUM(total_time)  AS total_time ,
  SUM(rows) AS rows , SUM(shared_blks_hit)  AS shared_blks_hit,
  SUM(shared_blks_read) AS shared_blks_read ,
  SUM(shared_blks_dirtied) AS shared_blks_dirtied,
  SUM(shared_blks_written) AS shared_blks_written , 
  SUM(local_blks_hit) AS local_blks_hit , 
  SUM(local_blks_read) AS local_blks_read , 
  SUM(local_blks_dirtied) AS local_blks_dirtied , 
  SUM(local_blks_written)  AS local_blks_written,
  SUM(temp_blks_read) AS temp_blks_read, 
  SUM(temp_blks_written) temp_blks_written , 
  SUM(blk_read_time) AS blk_read_time , 
  SUM(blk_write_time) AS blk_write_time
FROM 
  pg_stat_history
WHERE 
  queryid IS NULL AND
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT
GROUP BY database_id ;

Oras ng DB

to_char(interval '1 millisecond' * pg_total_stat_history_rec.total_time, 'HH24:MI:SS.MS')

Oras ng I/O

to_char(interval '1 millisecond' * ( pg_total_stat_history_rec.blk_read_time + pg_total_stat_history_rec.blk_write_time ), 'HH24:MI:SS.MS')

TOP10 SQL sa kabuuang_oras

Humiling

SELECT 
  queryid , 
  SUM(calls) AS calls ,
  SUM(total_time)  AS total_time  	
FROM 
  pg_stat_history
WHERE 
  queryid IS NOT NULL AND 
  database_id = DATABASE_ID AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT 
GROUP BY queryid 
ORDER BY 3 DESC 
LIMIT 10
------------------------------------------------- ----------------------------------- | NANGUNGUNANG 10 SQL AYON SA KABUUANG ORAS NG PAGSASANAY | #| queryid| mga tawag| tumatawag sa %| kabuuang_oras (ms) | dbtime % +----------+-----------+-----------+-----------+ ------ --------------------------+----------- | 1| 821760255| 2| .00001|00:03:23.141( 203141.681 ms.)| 5.42 | 2| 4152624390| 2| .00001|00:03:13.929( 193929.215 ms.)| 5.17 | 3| 1484454471| 4| .00001|00:02:09.129( 129129.057 ms.)| 3.44 | 4| 655729273| 1| .00000|00:02:01.869( 121869.981 ms.)| 3.25 | 5| 2460318461| 1| .00000|00:01:33.113( 93113.835 ms.)| 2.48 | 6| 2194493487| 4| .00001|00:00:17.377( 17377.868 ms.)| .46 | 7| 1053044345| 1| .00000|00:00:06.156( 6156.352 ms.)| .16 | 8| 3644780286| 1| .00000|00:00:01.063( 1063.830 ms.)| .03

TOP10 SQL sa kabuuang oras ng I/O

Humiling

SELECT 
  queryid , 
  SUM(calls) AS calls ,
  SUM(blk_read_time + blk_write_time)  AS io_time
FROM 
  pg_stat_history
WHERE 
  queryid IS NOT NULL AND 
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT
GROUP BY  queryid 
ORDER BY 3 DESC 
LIMIT 10
------------------------------------------------- ---------------------------------------------------- | NANGUNGUNANG 10 SQL NG KABUUANG ORAS NG I/O | #| queryid| mga tawag| tumatawag sa %| I/O time (ms)|db I/O time % +----+-----------+-----------+------ -------------------------+--------------------------------+----- ------ -- | 1| 4152624390| 2| .00001|00:08:31.616( 511616.592 ms.)| 31.06 | 2| 821760255| 2| .00001|00:08:27.099( 507099.036 ms.)| 30.78 | 3| 655729273| 1| .00000|00:05:02.209( 302209.137 ms.)| 18.35 | 4| 2460318461| 1| .00000|00:04:05.981( 245981.117 ms.)| 14.93 | 5| 1484454471| 4| .00001|00:00:39.144( 39144.221 ms.)| 2.38 | 6| 2194493487| 4| .00001|00:00:18.182( 18182.816 ms.)| 1.10 | 7| 1053044345| 1| .00000|00:00:16.611( 16611.722 ms.)| 1.01 | 8| 3644780286| 1| .00000|00:00:00.436( 436.205 ms.)| .03

TOP10 SQL sa pamamagitan ng maximum na oras ng pagpapatupad

Humiling

SELECT 
  id AS snapshotid , 
  queryid , 
  snapshot_timestamp ,  
  max_time 
FROM 
  pg_stat_history 
WHERE 
  queryid IS NOT NULL AND 
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT
ORDER BY 4 DESC 
LIMIT 10

------------------------------------------------- --------------------------------------- | NANGUNGUNANG 10 SQL NG MAX NA ORAS NG PAGSASANAY | #| snapshot| snapshotID| queryid| max_time (ms) +----+-------+-----------+--------- ----------------------------------------- | 1| 05.04.2019/01/03 4169:655729273| 00| 02| 01.869:121869.981:2( 04.04.2019 ms.) | 17| 00/4153/821760255 00:01| 41.570| 101570.841| 3:04.04.2019:16( 00 ms.) | 4146| 821760255/00/01 41.570:101570.841| 4| 04.04.2019| 16:00:4144( 4152624390 ms.) | 00| 01/36.964/96964.607 5:04.04.2019| 17| 00| 4151:4152624390:00(01 ms.) | 36.964| 96964.607/6/05.04.2019 10:00| 4188| 1484454471| 00:01:33.452(93452.150 ms.) | 7| 04.04.2019/17/00 4150:2460318461| 00| 01| 33.113:93113.835:8( 04.04.2019 ms.) | 15| 00/4140/1484454471 00:00| 11.892| 11892.302| 9:04.04.2019:16(00 ms.) | 4145| 1484454471/00/00 11.892:11892.302| 10| 04.04.2019| 17:00:4152( 1484454471 ms.) | 00| 00/11.892/11892.302 XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ms.) | XNUMX| XNUMX/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ms.)

TOP10 SQL by SHARED buffer read/write

Humiling

SELECT 
  id AS snapshotid , 
  queryid ,
  snapshot_timestamp , 
  shared_blks_read , 
  shared_blks_written 
FROM 
  pg_stat_history
WHERE 
  queryid IS NOT NULL AND 
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND
  ( shared_blks_read > 0 OR shared_blks_written > 0 )
ORDER BY 4 DESC  , 5 DESC 
LIMIT 10
------------------------------------------------- ------------------------------------------ | TOP10 SQL BY SHARED BUFFER READ/WRITE | #| snapshot| snapshotID| queryid| binasa ang mga nakabahaging bloke| nakabahaging mga bloke magsulat +----+-----+-----------+---------- -------------------------------------------------- | 1| 04.04.2019/17/00 4153:821760255| 797308| 0| 2| 04.04.2019 | 16| 00/4146/821760255 797308:0| 3| 05.04.2019| 01| 03 | 4169| 655729273/797158/0 4:04.04.2019| 16| 00| 4144| 4152624390 | 756514| 0/5/04.04.2019 17:00| 4151| 4152624390| 756514| 0 | 6| 04.04.2019/17/00 4150:2460318461| 734117| 0| 7| 04.04.2019 | 17| 00/4155/3644780286 52973:0| 8| 05.04.2019| 01| 03 | 4168| 1053044345/52818/0 9:04.04.2019| 15| 00| 4141| 2194493487 | 52813| 0/10/04.04.2019 16:00| 4147| 2194493487| 52813| 0 | XNUMX| XNUMX/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX| XNUMX | XNUMX| XNUMX/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX| XNUMX ------------------------------------------------- ------------------------------------------

Histogram ng pamamahagi ng mga kahilingan ayon sa maximum na oras ng pagpapatupad

kahilingan

SELECT  
  MIN(max_time) AS hist_min  , 
  MAX(max_time) AS hist_max , 
  (( MAX(max_time) - MIN(min_time) ) / hist_columns ) as hist_width
FROM 
  pg_stat_history 
WHERE 
  queryid IS NOT NULL AND
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT ;

SELECT 
  SUM(calls) AS calls
FROM 
  pg_stat_history 
WHERE 
  queryid IS NOT NULL AND
  database_id =DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND 
  ( max_time >= hist_current_min AND  max_time < hist_current_max ) ;
|------------------------------------------------ - ------------------------------------------ | MAX_TIME HISTOGRAM | KABUUANG TAWAG: 33851920 | MIN ORAS: 00:00:01.063 | MAX NA ORAS: 00:02:01.869 ------------------------------------------ --------------------------------------- | min na tagal| max na tagal| tumatawag +----------------------------------+-------------------------- ----------------------+---------- | 00:00:01.063( 1063.830 ms.) | 00:00:13.144( 13144.445 ms.) | 9 | 00:00:13.144( 13144.445 ms.) | 00:00:25.225( 25225.060 ms.) | 0 | 00:00:25.225( 25225.060 ms.) | 00:00:37.305( 37305.675 ms.) | 0 | 00:00:37.305( 37305.675 ms.) | 00:00:49.386( 49386.290 ms.) | 0 | 00:00:49.386( 49386.290 ms.) | 00:01:01.466( 61466.906 ms.) | 0 | 00:01:01.466( 61466.906 ms.) | 00:01:13.547( 73547.521 ms.) | 0 | 00:01:13.547( 73547.521 ms.) | 00:01:25.628( 85628.136 ms.) | 0 | 00:01:25.628( 85628.136 ms.) | 00:01:37.708( 97708.751 ms.) | 4 | 00:01:37.708( 97708.751 ms.) | 00:01:49.789( 109789.366 ms.) | 2 | 00:01:49.789( 109789.366 ms.) | 00:02:01.869( 121869.981 ms.) | 0

TOP10 Snapshots ayon sa Query per Second

kahilingan

--pg_qps.sql
--Calculate Query Per Second 
CREATE OR REPLACE FUNCTION pg_qps( pg_stat_history_id integer ) RETURNS double precision AS $$
DECLARE
 pg_stat_history_rec record ;
 prev_pg_stat_history_id integer ;
 prev_pg_stat_history_rec record;
 total_seconds double precision ;
 result double precision;
BEGIN 
  result = 0 ;
  
  SELECT *
  INTO pg_stat_history_rec
  FROM 
    pg_stat_history
  WHERE id = pg_stat_history_id ;

  IF pg_stat_history_rec.snapshot_timestamp IS NULL 
  THEN
    RAISE EXCEPTION 'ERROR - Not found pg_stat_history for id = %',pg_stat_history_id;
  END IF ;  
  
 --RAISE NOTICE 'pg_stat_history_id = % , snapshot_timestamp = %', pg_stat_history_id , 
 pg_stat_history_rec.snapshot_timestamp ;
  
  SELECT 
    MAX(id)   
  INTO
    prev_pg_stat_history_id
  FROM
    pg_stat_history
  WHERE 
    database_id = pg_stat_history_rec.database_id AND
	queryid IS NULL AND
	id < pg_stat_history_rec.id ;

  IF prev_pg_stat_history_id IS NULL 
  THEN
    RAISE NOTICE 'Not found previous pg_stat_history shapshot for id = %',pg_stat_history_id;
	RETURN NULL ;
  END IF;
  
  SELECT *
  INTO prev_pg_stat_history_rec
  FROM 
    pg_stat_history
  WHERE id = prev_pg_stat_history_id ;
  
  --RAISE NOTICE 'prev_pg_stat_history_id = % , prev_snapshot_timestamp = %', prev_pg_stat_history_id , prev_pg_stat_history_rec.snapshot_timestamp ;    

  total_seconds = extract(epoch from ( pg_stat_history_rec.snapshot_timestamp - prev_pg_stat_history_rec.snapshot_timestamp ));
  
  --RAISE NOTICE 'total_seconds = % ', total_seconds ;    
  
  --RAISE NOTICE 'calls = % ', pg_stat_history_rec.calls ;      
  
  IF total_seconds > 0 
  THEN
    result = pg_stat_history_rec.calls / total_seconds ;
  ELSE
   result = 0 ; 
  END IF;
   
 RETURN result ;
END
$$ LANGUAGE plpgsql;


SELECT 
  id , 
  snapshot_timestamp ,
  calls , 	
  total_time , 
  ( select pg_qps( id )) AS QPS ,
  blk_read_time ,
  blk_write_time
FROM 
  pg_stat_history
WHERE 
  queryid IS NULL AND 
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND
  ( select pg_qps( id )) IS NOT NULL 
ORDER BY 5 DESC 
LIMIT 10
|------------------------------------------------ - ------------------------------------------ | TOP10 Snapshot na inorder ng mga numero ng QueryPerSeconds -------------------------------------------- ------------------------------------------------- ------------------------------------------------- | #| snapshot| snapshotID| mga tawag| kabuuang dbtime| QPS| I/O time| I/O time % +------+-------------------------------+------- ----+----------------------------------+---------- --------------------------+----------- | 1| 04.04.2019/20/04 4161:5758631| 00| 06| 30.513:390513.926:1573.396( 00 ms.)| 00| 01.470:1470.110:376( 2 ms.)| .04.04.2019 | 17| 00/4149/3529197 00:11| 48.830| 708830.618| 980.332:00:12( 47.834 ms.)| 767834.052| 108.324:3:04.04.2019( 16 ms.)| 00 | 4143| 3525360/00/10 13.492:613492.351| 979.267| 00| 08:41.396:521396.555( 84.988 ms.)| 4| 04.04.2019:21:03(4163 ms.)| 2781536 | 00| 03/06.470/186470.979 785.745:00| 00| 00.249| 249.865:134:5( 04.04.2019 ms.)| 19| 03:4159:2890362(00 ms.)| .03 | 16.784| 196784.755 776.979:00| 00| 01.441| 1441.386:732:6( 04.04.2019 ms.)| 14| 00:4137:2397326( 00 ms.)| .04 | 43.033| 283033.854/665.924/00 00:00.024| 24.505| 009| 7:04.04.2019:15( 00 ms.)| 4139| 2394416:00:04(51.435 ms.)| .291435.010 | 665.116| 00/00/12.025 12025.895:4.126| 8| 04.04.2019| 13:00:4135( 2373043 ms.)| 00| 04:26.791:266791.988( 659.179 ms.)| 00 | 00| 00.064 64.261:024| 9| 05.04.2019| 01:03:4167( 4387191 ms.)| 00| 06:51.380:411380.293( 609.332 ms.)| .00 | 05| 18.847/318847.407/77.507 10:04.04.2019| 18| 01| 4157:1145596:00( 01 ms.)| 19.217| 79217.372:313.004:00( 00 ms.)| 01.319 | 1319.676| 1.666/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ms.)| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ms.)| XNUMX

Oras-oras na Kasaysayan ng Pagpapatupad sa QueryPerSeconds at I/O Time

Humiling

SELECT 
  id , 
  snapshot_timestamp ,
  calls , 	
  total_time , 
  ( select pg_qps( id )) AS QPS ,
  blk_read_time ,
  blk_write_time
FROM 
  pg_stat_history
WHERE 
  queryid IS NULL AND 
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT
ORDER BY 2
|-----------------------------------------------------------------------------------------------
| HOURLY EXECUTION HISTORY  WITH QueryPerSeconds and I/O Time
-----------------------------------------------------------------------------------------------------------------------------------------------
| QUERY PER SECOND HISTORY
|    #|          snapshot| snapshotID|      calls|                      total dbtime|        QPS|                          I/O time| I/O time %
+-----+------------------+-----------+-----------+----------------------------------+-----------+----------------------------------+-----------
|    1|  04.04.2019 11:00|       4131|       3747|  00:00:00.835(       835.374 ms.)|      1.041|  00:00:00.000(          .000 ms.)|       .000
|    2|  04.04.2019 12:00|       4133|    1002722|  00:01:52.419(    112419.376 ms.)|    278.534|  00:00:00.149(       149.105 ms.)|       .133
|    3|  04.04.2019 13:00|       4135|    2373043|  00:04:26.791(    266791.988 ms.)|    659.179|  00:00:00.064(        64.261 ms.)|       .024
|    4|  04.04.2019 14:00|       4137|    2397326|  00:04:43.033(    283033.854 ms.)|    665.924|  00:00:00.024(        24.505 ms.)|       .009
|    5|  04.04.2019 15:00|       4139|    2394416|  00:04:51.435(    291435.010 ms.)|    665.116|  00:00:12.025(     12025.895 ms.)|      4.126
|    6|  04.04.2019 16:00|       4143|    3525360|  00:10:13.492(    613492.351 ms.)|    979.267|  00:08:41.396(    521396.555 ms.)|     84.988
|    7|  04.04.2019 17:00|       4149|    3529197|  00:11:48.830(    708830.618 ms.)|    980.332|  00:12:47.834(    767834.052 ms.)|    108.324
|    8|  04.04.2019 18:01|       4157|    1145596|  00:01:19.217(     79217.372 ms.)|    313.004|  00:00:01.319(      1319.676 ms.)|      1.666
|    9|  04.04.2019 19:03|       4159|    2890362|  00:03:16.784(    196784.755 ms.)|    776.979|  00:00:01.441(      1441.386 ms.)|       .732
|   10|  04.04.2019 20:04|       4161|    5758631|  00:06:30.513(    390513.926 ms.)|   1573.396|  00:00:01.470(      1470.110 ms.)|       .376
|   11|  04.04.2019 21:03|       4163|    2781536|  00:03:06.470(    186470.979 ms.)|    785.745|  00:00:00.249(       249.865 ms.)|       .134
|   12|  04.04.2019 23:03|       4165|    1443155|  00:01:34.467(     94467.539 ms.)|    200.438|  00:00:00.015(        15.287 ms.)|       .016
|   13|  05.04.2019 01:03|       4167|    4387191|  00:06:51.380(    411380.293 ms.)|    609.332|  00:05:18.847(    318847.407 ms.)|     77.507
|   14|  05.04.2019 02:03|       4171|     189852|  00:00:10.989(     10989.899 ms.)|     52.737|  00:00:00.539(       539.110 ms.)|      4.906
|   15|  05.04.2019 03:01|       4173|       3627|  00:00:00.103(       103.000 ms.)|      1.042|  00:00:00.004(         4.131 ms.)|      4.010
|   16|  05.04.2019 04:00|       4175|       3627|  00:00:00.085(        85.235 ms.)|      1.025|  00:00:00.003(         3.811 ms.)|      4.471
|   17|  05.04.2019 05:00|       4177|       3747|  00:00:00.849(       849.454 ms.)|      1.041|  00:00:00.006(         6.124 ms.)|       .721
|   18|  05.04.2019 06:00|       4179|       3747|  00:00:00.849(       849.561 ms.)|      1.041|  00:00:00.000(          .051 ms.)|       .006
|   19|  05.04.2019 07:00|       4181|       3747|  00:00:00.839(       839.416 ms.)|      1.041|  00:00:00.000(          .062 ms.)|       .007
|   20|  05.04.2019 08:00|       4183|       3747|  00:00:00.846(       846.382 ms.)|      1.041|  00:00:00.000(          .007 ms.)|       .001
|   21|  05.04.2019 09:00|       4185|       3747|  00:00:00.855(       855.426 ms.)|      1.041|  00:00:00.000(          .065 ms.)|       .008
|   22|  05.04.2019 10:00|       4187|       3797|  00:01:40.150(    100150.165 ms.)|      1.055|  00:00:21.845(     21845.217 ms.)|     21.812

Teksto ng lahat ng SQL-select

Humiling

SELECT 
  queryid , 
  query 
FROM 
  pg_stat_history
WHERE 
  queryid IS NOT NULL AND 
  database_id = DATABASE_ID  AND
  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT
GROUP BY queryid , query

Kabuuan

Tulad ng nakikita mo, gamit ang medyo simpleng paraan, makakakuha ka ng maraming kapaki-pakinabang na impormasyon tungkol sa workload at estado ng database.

Tandaan:Kung itatala namin ang queryid sa mga query, makukuha namin ang kasaysayan para sa isang hiwalay na query (upang makatipid ng espasyo, ang mga ulat para sa isang hiwalay na query ay tinanggal).

Kaya, magagamit at kinokolekta ang istatistikal na data sa pagganap ng query.
Ang unang yugto ng "pagkolekta ng istatistikal na data" ay nakumpleto.

Maaari kang magpatuloy sa pangalawang yugto - "pagse-set up ng mga sukatan ng pagganap."
Pagsubaybay sa pagganap ng mga query sa PostgreSQL. Bahagi 1 - pag-uulat

Ngunit ito ay isang ganap na naiibang kuwento.

Upang patuloy ...

Pinagmulan: www.habr.com

Bumili ng maaasahang pagho-host para sa mga site na may proteksyon ng DDoS, mga server ng VPS VDS 🔥 Bumili ng maaasahang website hosting na may proteksyon ng DDoS, VPS VDS servers | ProHoster