Inĝeniero - tradukita el la latina - inspirita.
Inĝeniero povas fari ion ajn. (c) R. Diesel.
Epigrafoj.
Aŭ rakonto pri kial datumbaza administranto bezonas memori sian programan pasintecon.
Antaŭparolo
Ĉiuj nomoj estis ŝanĝitaj. Matĉoj estas hazardaj. La materialo estas nur la persona opinio de la aŭtoro.
Malgarantio pri garantioj: en la planita serio de artikoloj ne estos detala kaj preciza priskribo de la uzataj tabeloj kaj skriptoj. Materialoj ne povas esti tuj uzataj "TIAL".
Unue, pro la granda kvanto da materialo,
due, pro la akreco kun la produktada bazo de vera kliento.
Tial, nur ideoj kaj priskriboj en la plej ĝenerala formo estos donitaj en la artikoloj.
Eble estonte la sistemo kreskos al la nivelo de afiŝado sur GitHub, aŭ eble ne. La tempo montros.
La komenco de la rakonto -
Kio okazis kiel rezulto, en la plej ĝeneralaj terminoj - "
Kial mi bezonas ĉion ĉi?
Nu, unue, por ne forgesi vin mem, memorante la glorajn tagojn en emeritiĝo.
Due, sistemigi tion, kio estis skribita. Por jam mi, foje mi komencas konfuziĝi kaj forgesi apartajn partojn.
Nu, kaj plej grave - subite ĝi povas esti utila por iu kaj helpi ne reinventi la radon kaj ne kolekti rastilon. Alivorte, plibonigu vian karmon (ne Khabrovsky). Ĉar la plej valora afero en ĉi tiu mondo estas ideoj. La ĉefa afero estas trovi ideon. Kaj traduki la ideon en realecon jam estas pure teknika afero.
Do ni komencu malrapide...
Formulo de la problemo.
Disponebla:
PostgreSQL (10.5), miksita ŝarĝo (OLTP+DSS), meza ĝis malpeza ŝarĝo, gastigita en la AWS-nubo.
Ne ekzistas datumbaza monitorado, infrastruktura monitorado estas prezentita kiel normaj AWS-iloj en minimuma agordo.
Bezonata:
Monitoru la agadon kaj staton de la datumbazo, trovu kaj havu komencajn informojn por optimumigi pezajn datumbazajn demandojn.
Mallonga enkonduko aŭ analizo de solvoj
Komence, ni provu analizi la eblojn por solvi la problemon el la vidpunkto de kompara analizo de la avantaĝoj kaj problemoj por la inĝeniero, kaj lasu tiujn, kiuj supozeble estas en la persona listo, trakti la avantaĝojn kaj perdojn. de administrado.
Opcio 1 - "Laborante laŭpeto"
Ni lasas ĉion kiel ĝi estas. Se la kliento ne kontentas pri io en la sano, agado de la datumbazo aŭ aplikaĵo, li sciigos la DBA-inĝenierojn per retpoŝto aŭ kreante okazaĵon en la biletujo.
Inĝeniero, ricevinte sciigon, komprenos la problemon, proponos solvon aŭ arkivos la problemon, esperante, ke ĉio solvos sin, kaj ĉiuokaze, ĉio baldaŭ estos forgesita.
Zingibra pano kaj benkoj, kontuziĝoj kaj tuberojZingibra pano kaj benkoj:
1. Nenio kroma fari
2. Ĉiam estas la ŝanco eliri kaj malpuriĝi.
3. Multan tempon, kiun vi povas elspezi memstare.
Kontuzo kaj tuberoj:
1. Pli aŭ malpli frue, la kliento pensos pri la esenco de esti kaj universala justeco en ĉi tiu mondo kaj denove faros al si la demandon - kial mi pagas al ili mian monon? La sekvo estas ĉiam la sama - la sola demando estas kiam la kliento enuiĝas kaj svingas adiaŭon. Kaj la manĝilo estas malplena. Estas malgaja.
2. La evoluo de inĝeniero estas nula.
3. Malfacilaĵoj en planado de laboro kaj ŝarĝo
Opcio 2 - "Dancu per tamburinoj, surmetu kaj surmetu ŝuojn"
Paragrafo 1-Kial ni bezonas monitoran sistemon, ni ricevos ĉiujn petojn. Ni lanĉas amason da ĉiaj demandoj al la datumvortaro kaj dinamikaj vidoj, ŝaltas ĉiajn nombrilojn, alportas ĉion en tabelojn, periode analizas listojn kaj tabelojn, kvazaŭ. Kiel rezulto, ni havas belajn aŭ ne tre grafikaĵojn, tabelojn, raportojn. La ĉefa afero - tio estus pli, pli.
Paragrafo 2-Generu agadon-kuru la analizon de ĉio ĉi.
Paragrafo 3-Ni preparas certan dokumenton, ni nomas ĉi tiun dokumenton, simple - "kiel ni ekipas la datumbazon."
Paragrafo 4— La kliento, vidante ĉi tiun tutan grandiozecon de grafikaĵoj kaj figuroj, estas en infana naiva konfido — nun ĉio funkcios por ni, baldaŭ. Kaj, facile kaj sendolore disiĝas de siaj financaj rimedoj. Administrado ankaŭ certas, ke niaj inĝenieroj laboras forte. Maksimuma ŝarĝo.
Paragrafo 5- Ripetu la paŝon 1 regule.
Zingibra pano kaj benkoj, kontuziĝoj kaj tuberojZingibra pano kaj benkoj:
1. La vivo de administrantoj kaj inĝenieroj estas simpla, antaŭvidebla kaj plena de agado. Ĉio zumas, ĉiuj estas okupataj.
2. La vivo de la kliento ankaŭ ne estas malbona - li ĉiam certas, ke vi bezonas iom pacienci kaj ĉio funkcios. Ĝi ne pliboniĝas, nu, nu – ĉi tiu mondo estas maljusta, en la venonta vivo – vi estos bonŝanca.
Kontuzo kaj tuberoj:
1. Pli aŭ malpli frue, estos pli inteligenta provizanto de simila servo, kiu faros la samon, sed iom pli malmultekosta. Kaj se la rezulto estas la sama, kial pagi pli. Kiu denove kondukos al la malapero de la nutrilo.
2. Estas enuiga. Kiel enuiga ajna eta signifoplena agado.
3. Kiel en la antaŭa versio - neniu evoluo. Sed por inĝeniero, la minusaĵo estas, ke, male al la unua opcio, ĉi tie vi devas konstante generi IDB. Kaj tio bezonas tempon. Kiu povas esti elspezita por la avantaĝo de via amato. Ĉar vi ne povas zorgi pri vi mem, ĉiuj zorgas pri vi.
Opcio 3-Ne necesas inventi biciklon, vi devas aĉeti ĝin kaj veturi ĝin.
Inĝenieroj de aliaj kompanioj konscie manĝas picon kun biero (ho, la gloraj tempoj de Sankt-Peterburgo en la 90-aj jaroj). Ni uzu monitorajn sistemojn, kiuj estas faritaj, sencimigitaj kaj funkciantaj, kaj ĝenerale ili alportas avantaĝojn (nu, almenaŭ al siaj kreintoj).
Zingibra pano kaj benkoj, kontuziĝoj kaj tuberojZingibra pano kaj benkoj:
1. Ne necesas perdi tempon inventante tion, kio jam estas elpensita. Prenu kaj uzu.
2. Monitorsistemoj ne estas verkitaj de malsaĝuloj, kaj kompreneble ili estas utilaj.
3. Laborantaj monitoraj sistemoj kutime provizas utilajn filtritajn informojn.
Kontuzo kaj tuberoj:
1. La inĝeniero ĉi-kaze ne estas inĝeniero, sed nur uzanto de la produkto de iu alia aŭ uzanto.
2. La kliento devas esti konvinkita pri la bezono aĉeti ion, kion li ĝenerale ne volas kompreni, kaj li ne devus, kaj ĝenerale la buĝeto por la jaro estas aprobita kaj ne ŝanĝiĝos. Tiam vi devas asigni apartan rimedon, agordi ĝin por specifa sistemo. Tiuj. Unue vi devas pagi, pagi kaj pagi denove. Kaj la kliento estas avara. Ĉi tio estas la normo de ĉi tiu vivo.
Kion fari, Ĉerniŝevskij? Via demando estas tre trafa. (Kun)
En ĉi tiu aparta kazo kaj la nuna situacio, vi povas fari iom malsame - ni faru nian propran monitoran sistemon.
Nu, ne sistemo, kompreneble, en la plena senco de la vorto, ĉi tio estas tro laŭta kaj aroganta, sed almenaŭ iel faciligu al vi mem kaj kolektu pli da informoj por solvi agadojn incidentojn. Por ne trovi vin en situacio - "iru tien, mi ne scias kien, trovu tion, mi ne scias kion."
Kio estas la avantaĝoj kaj malavantaĝoj de ĉi tiu opcio:
Pros:
1. Estas interese. Nu, almenaŭ pli interesa ol la konstanta "malgrandigi datumdosieron, ŝanĝi tabelspacon, ktp."
2. Ĉi tiuj estas novaj kapabloj kaj nova evoluo. Kiu estonte pli aŭ malpli frue donos merititajn zingibrbukojn kaj benkojn.
Kons:
1. Devas labori. Laboru multe.
2. Vi devos regule klarigi la signifon kaj perspektivojn de ĉiu agado.
3. Io devos esti oferita, ĉar la sola rimedo disponebla al la inĝeniero – la tempo – estas limigita de la Universo.
4. La plej malbona kaj plej malagrabla - sekve, rubo kiel "Ne muso, ne rano, sed nekonata besteto" povas rezulti.
Kiu ne riskas ion, ne trinkas ĉampanon.
Do, la amuzo komenciĝas.
Ĝenerala ideo - skema
(Ilustraĵo prenita el artikolo «
Klarigo:
- La cela datumbazo estas instalita per la norma etendo de PostgreSQL "pg_stat_statements".
- En la monitora datumbazo, ni kreas aron da servotabeloj por stoki la pg_stat_statements-historion en la komenca etapo kaj por agordi metrikojn kaj monitoradon estonte.
- Sur la monitora gastiganto, ni kreas aron da bash-skriptoj, inkluzive de tiuj por generi incidentojn en la biletsistemo.
Servaj tabloj
Komence, skeme simpligita ERD, kio okazis finfine:
Mallonga priskribo de la tabelojfinpunkto - gastiganto, konektopunkto al la petskribo
DataBase - datumbazaj opcioj
pg_stat_historio - historia tabelo por stoki provizorajn momentfotojn de la pg_stat_statements-vido de la cela datumbazo
metrika_glosaro - Vortaro de agado-metrikoj
metriko_agordo - agordo de individuaj metrikoj
metriko - specifa metriko por la peto, kiu estas monitorita
metrika_alerta_historio - historio de agado-avertoj
log_demando - servotabelo por stoki analizitajn rekordojn de la postgreSQL-protokolo-dosiero elŝutita de AWS
bazlinio - parametroj de la tempoperiodo uzata kiel bazo
kontrolpunkto - agordo de metrikoj por kontroli la staton de la datumbazo
kontrolpunkto_alert_historio - averta historio de datumbaza statokontrolaj metrikoj
pg_stat_db_queries — servotabelo de aktivaj petoj
agado_log — tabelo de servo de agado
kaptilo_oido - kaptilo-agorda servotabelo
Etapo 1 - kolektu rendimentostatistikojn kaj ricevu raportojn
Tabelo estas uzata por konservi statistikajn informojn. pg_stat_historio
pg_stat_history tabelstrukturo
Tabelo "public.pg_stat_history" Kolumno | tajpu | Modifiloj--------------------+-------------------- --+---- -------------------------------- id | entjero | ne nula defaŭlta nextval('pg_stat_history_id_seq'::regclass) momentfoto_timestamp | tempomarko sen horzono | datumbazo_id | entjero | dbid | oid | uzulo | oid | queryid | bigint | konsulto | teksto | vokoj | bigint | tuta_tempo | duobla precizeco | min_tempo | duobla precizeco | maksimuma_tempo | duobla precizeco | meztempo | duobla precizeco | stddev_time | duobla precizeco | vicoj | bigint | shared_blks_hit | bigint | shared_blks_read | bigint | shared_blks_dirtied | bigint | shared_blks_written | bigint | loka_blks_hit | bigint | loka_blks_read | bigint | lokaj_blks_malpuraj | bigint | lokaj_blks_skribitaj | bigint | temp_blks_read | bigint | temp_blks_skribitaj | bigint | blk_legi_tempo | duobla precizeco | blk_skribi_tempo | duobla precizeco | bazlinio_id | entjero | Indeksoj: "pg_stat_history_pkey" PRIMA Ŝlosilo, btree (id) "database_idx" btree (database_id) "queryid_idx" btree (queryid) "snapshot_timestamp_idx" btree (snapshot_timestamp) Fremd-ŝlosila limo FOREIGN-datumbazo_FER_EJ_KID_ID_: datumbazo (id ) ON FORIGI KASKADO
Kiel vi povas vidi, la tabelo estas nur akumula viddatumo pg_stat_statements en la cela datumbazo.
La uzo de ĉi tiu tablo estas tre simpla.
pg_stat_historio reprezentos la akumulitajn statistikojn de demanda ekzekuto por ĉiu horo. Komence de ĉiu horo, post plenigo de la tabelo, statistikoj pg_stat_statements restarigi kun pg_stat_statements_reset ().
Notu: statistikoj estas kolektitaj por petoj kun daŭro de pli ol 1 sekundo.
Plenigante la tabelon pg_stat_history
--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;
Kiel rezulto, post certa tempodaŭro en la tabelo pg_stat_historio ni havos aron da momentfotoj de la enhavo de la tabelo pg_stat_statements cela datumbazo.
Fakte raportante
Uzante simplajn demandojn, vi povas ricevi sufiĉe utilajn kaj interesajn raportojn.
Agregaj datumoj por difinita tempodaŭro
Peto
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 ;
D.B. Tempo
to_char(intervalo '1 milisekundo' * pg_total_stat_history_rec.total_time, 'HH24:MI:SS.MS')
I/O Tempo
to_char(intervalo '1 milisekundo' * ( pg_total_stat_history_rec.blk_read_time + pg_total_stat_history_rec.blk_write_time ), 'HH24:MI:SS.MS')
TOP10 SQL per totala_tempo
Peto
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
------------------------------------------------- ------------------------------------ | TOP10 SQL LAŬ TUTA EKZEKUTA TEMPO | #| queryid| vokoj| vokas %| tuta_tempo (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 per totala I/O-tempo
Peto
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
------------------------------------------------- -------------------------------------- | TOP10 SQL LAŬ TOTA I/O-TEMPO | #| queryid| vokoj| vokas %| I/O tempo (ms)|db I/O tempo % +----+-----------+-----------+------ -----+-------------------------------+----------- -- | 1| 4152624390| 2| .00001|00:08:31.616( 511616.592 ms.)| la 31.06-an de junio | 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 per maksimuma tempo de ekzekuto
Peto
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
------------------------------------------------- ------------------------------------ | TOP10 SQL PER MAKUSMA EKZEKUTA TEMPO | #| momentfoto| snapshotID| queryid| max_tempo (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 per SHARED bufro legi/skribi
Peto
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 PER KOMUNITA BUFFER LEGADO/SKRIBA | #| momentfoto| snapshotID| queryid| komunaj blokoj legi| komunaj blokoj skribu +----+------------------+-----------+---------- -+---------------------+--------------------- | 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 ------------------------------------------------- ------------------------------------------------
Histogramo de demanddistribuo per maksimuma ekzekuttempo
Petoj
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 HISTOGRAMO | TOTALVOKOJ : 33851920 | MIN TEMPO : 00:00:01.063 | MAX TEMPO : 00:02:01.869 --------------------------------- -------- ---------------------------- | min daŭro| maksimuma daŭro| vokoj +---------------------------------+-------------- ---------------------+---------- | 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 Momentfotoj per Demando por Sekundo
Petoj
--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 Momentfotoj ordigitaj de QueryPerSeconds-nombroj ------------------------------------- ------ ------------------------------------------- ------ ------------------------------------------- | #| momentfoto| snapshotID| vokoj| tuta dbtempo| QPS | I/O tempo | I/O tempo % +-----+------------------+-----------+------- ----+---------------------------------+---------- -+---------------------------------+----------- | 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:14( 00 ms.)| 4137| 2397326:00:04( 43.033 ms.)| .283033.854 | 665.924| 00/00/00.024 24.505:009 | 7| 04.04.2019| 15:00:4139( 2394416 ms.)| 00| 04:51.435:291435.010( 665.116 ms.)| .00 | 00| 12.025/12025.895/4.126 8:04.04.2019| 13| 00| 4135:2373043:00( 04 ms.)| 26.791| 266791.988:659.179:00( 00 ms.)| 00.064 | 64.261| 024/9/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 | 10| 04.04.2019/18/01 4157:1145596| 00| 01| 19.217:79217.372:313.004( 00 ms.)| 00| 01.319:1319.676:1.666( XNUMX ms.)| XNUMX | XNUMX| XNUMX/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ms.)| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ms.)| XNUMX
Hora Ekzekutado-Historio kun QueryPerSeconds kaj I/O Tempo
Peto
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 de ĉiuj SQL-elektoj
Peto
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
La rezulto
Kiel vi povas vidi, per sufiĉe simplaj rimedoj, vi povas akiri multajn utilajn informojn pri la laborkvanto kaj la stato de la datumbazo.
Notu:Se vi fiksas la keryid en la demandoj, tiam ni ricevos la historion por aparta peto (por ŝpari spacon, raportoj por aparta peto estas preterlasitaj).
Do, statistikaj datumoj pri demanda rendimento estas haveblaj kaj kolektitaj.
La unua etapo "kolekto de statistikaj datumoj" estas finita.
Vi povas daŭrigi al la dua etapo - "agordo de agado-metrikoj".
Sed tio estas tute alia historio.
Daŭrigota…
fonto: www.habr.com