Engineer - isinalin mula sa Latin - inspirasyon.
Ang isang engineer ay maaaring gumawa ng kahit ano. (c) R. Diesel.
Mga Epigraph.

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-"'.
Ano ang nangyari bilang isang resulta, sa pinaka-pangkalahatang mga termino - "»
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.

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

(Ilustrasyon na kinuha mula sa artikulo «")
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:

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 CASCADEGaya 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."

Ngunit ito ay isang ganap na naiibang kuwento.
Upang patuloy ...
Pinagmulan: www.habr.com
