{"id":32353,"date":"2019-10-31T21:46:32","date_gmt":"2019-10-31T18:46:32","guid":{"rendered":"https:\/\/prohoster.info\/blog\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\/"},"modified":"2019-10-31T21:46:32","modified_gmt":"2019-10-31T18:46:32","slug":"monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","title":{"rendered":"\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 - Reporting","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ingenieur - \u00fcbersetzt aus dem Lateinischen - inspiriert.<br \/>\nEin Ingenieur kann alles. (c) R.Diesel.<br \/>\n<i>Epigrafen.<\/i><br \/>\n<img decoding=\"async\" alt=\"\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 - Reporting\" src=\"\/wp-content\/uploads\/2019\/04\/9a2640267ea05006b94e03642b864ddc.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Oder die Geschichte dar\u00fcber, warum ein Datenbankadministrator an seine Programmiervergangenheit denken sollte. <\/i><\/p>\n<h2>Vorwort<\/h2>\n<p>\nAlle Namen wurden ge\u00e4ndert. Zuf\u00e4llige \u00dcbereinstimmungen. Das Material stellt ausschlie\u00dflich die pers\u00f6nliche Meinung des Autors dar.<\/p>\n<blockquote><p><b>Haftungsausschluss f\u00fcr Garantien:<\/b> <i>In dem geplanten Artikelzyklus wird es keine detaillierte und pr\u00e4zise Beschreibung der verwendeten Tabellen und Skripte geben. Materialien k\u00f6nnen nicht sofort \"AS IS\" verwendet werden. <br \/>\nErstens aufgrund des gro\u00dfen Materialumfangs, <br \/>\nzweitens aufgrund der Anpassung an die Produktionsdatenbank eines realen Kunden. <br \/>\nDeshalb werden in den Artikeln nur Ideen und Beschreibungen in den allgemeinsten Z\u00fcgen dargestellt. <br \/>\nVielleicht wird das System in Zukunft auf das Niveau eines Uploads auf GitHub wachsen, vielleicht auch nicht. Die Zeit wird es zeigen.<\/i><\/p><\/blockquote>\n<p>\nDer Beginn der Geschichte - \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/icl_services\/blog\/446314\/\">Erinnerst du dich, wie alles begann<\/a><\/noindex>\u00bb.<br \/>\nWas dabei herauskam, in groben Z\u00fcgen - \"<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444988\/\">\ud83e\udd47Wir begr\u00fc\u00dfen den Service von Cloudflare an den Adressen 1.1.1.1 und 1.0.0.1, oder \"das Angebot \u00f6ffentlicher DNS ist gewachsen!\" | ProHoster<\/a><\/noindex>\u00bb<\/p>\n<h2>Warum brauche ich das alles?<\/h2>\n<p>\nNun, erstens, um selbst nicht zu vergessen, wenn ich im Ruhestand an die glorreichen Zeiten zur\u00fcckdenke. <br \/>\nZweitens, um das Geschriebene zu systematisieren. Denn selbst ich fange manchmal an, mich in einzelnen Teilen zu verwirren und zu vergessen. <\/p>\n<p>Und das Wichtigste ist - vielleicht k\u00f6nnte es jemandem n\u00fctzlich sein und helfen, das Rad nicht neu zu erfinden und keine Fehler zu machen. Mit anderen Worten, seine Karma zu verbessern (nicht das von Habr). Denn das Wertvollste in dieser Welt sind Ideen. Das Wichtigste ist, die Idee zu finden. Die Idee in die Realit\u00e4t umzusetzen, das ist bereits eine rein technische Frage.<\/p>\n<p>Also, fangen wir langsam an...<\/p>\n<h2>Die Aufgabenstellung.<\/h2>\n<p><\/p>\n<h3>Verf\u00fcgbar: <\/h3>\n<p>\nPostgreSQL-Datenbank (10.5), gemischte Lastart (OLTP+DSS), mittlere bis geringe Belastung, in der AWS-Cloud gehostet. <br \/>\nDie Datenbank\u00fcberwachung fehlt, die Infrastruktur\u00fcberwachung erfolgt mit den standardm\u00e4\u00dfigen AWS-Tools in minimaler Konfiguration.<\/p>\n<h3>Erforderlich:<\/h3>\n<p>\nDie Leistung und den Zustand der Datenbank \u00fcberwachen, Informationen zur Optimierung von schweren Abfragen zur Verf\u00fcgung haben.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2>Kurze Einleitung oder Analyse der L\u00f6sungsm\u00f6glichkeiten<\/h2>\n<p>\nZun\u00e4chst versuchen wir, die L\u00f6sungsm\u00f6glichkeiten aus der Sicht eines vergleichenden Nutzen- und Nachteilanalyses f\u00fcr den Ingenieur zu betrachten, w\u00e4hrend das Management sich um Nutzen und Verluste k\u00fcmmern kann, wie es im Stellenplan vorgesehen ist.<\/p>\n<h3>Option 1 - \"On-Demand-Arbeiten\"<\/h3>\n<p>\nWir lassen alles wie es ist. Wenn der Auftraggeber mit der Funktionsweise oder Leistung der Datenbank oder Anwendung unzufrieden ist, wird er die DBA-Ingenieure per E-Mail benachrichtigen oder einen Vorfall im Ticketsystem erstellen. <br \/>\nDer Ingenieur, der die Benachrichtigung erh\u00e4lt, wird das Problem analysieren, eine L\u00f6sung vorschlagen oder das Problem auf die lange Bank schieben, in der Hoffnung, dass sich alles von selbst l\u00f6st, und ohnehin wird alles bald vergessen sein.<br \/>\n<b class=\"spoiler_title\">Pfeffern\u00fcsse und Krapfen, blaue Flecken und Beulen<\/b><b>Pfeffern\u00fcsse und Krapfen:<\/b><br \/>\n1. Es ist nicht notwendig, etwas \u00dcberfl\u00fcssiges zu tun.<br \/>\n2. Es gibt immer die M\u00f6glichkeit, sich herauszuwinden und sich zu dr\u00fccken. <br \/>\n3. Eine Menge Zeit, die man nach eigenem Ermessen verschwenden kann.<br \/>\n<b>Blaue Flecken und Beulen:<\/b><br \/>\n1. Fr\u00fcher oder sp\u00e4ter wird der Auftraggeber \u00fcber die Essenz der Existenz und die universelle Gerechtigkeit in dieser Welt nachdenken und sich erneut die Frage stellen \u2013 wof\u00fcr bezahle ich ihnen mein Geld? Die Konsequenz ist immer gleich \u2013 die Frage ist nur, wann der Auftraggeber gelangweilt wird und auf Wiedersehen winkt. Und die Futterstelle wird leer sein. Das ist traurig.<br \/>\n2. Die Entwicklung des Ingenieurs \u2013 Null.<br \/>\n3. Schwierigkeiten bei der Planung der Arbeit und der Auslastung. <\/p>\n<h3>Option 2 \u2013 \u201eWir tanzen mit Trommeln, verkaufen und kleiden ein.\u201c<\/h3>\n<p>\n<b>Punkt 1<\/b>- Warum brauchen wir ein \u00dcberwachungssystem? Wir werden alles \u00fcber Anfragen erhalten. Eine ganze Reihe von Anfragen an das Datenlexikon und dynamische Ansichten starten, verschiedene Z\u00e4hler aktivieren, alles in Tabellen zusammenfassen, und gelegentlich sozusagen Listen und Tabellen analysieren. In der Folge erhalten wir sch\u00f6ne oder weniger sch\u00f6ne Grafiken, Tabellen, Berichte. Das Wichtigste ist, dass es mehr und mehr gibt.<br \/>\n<b>Punkt 2<\/b>- Wir generieren Aktivit\u00e4t \u2013 analysieren all das.<br \/>\n<b>Punkt 3<\/b>- Wir bereiten ein Dokument vor, nennen es einfach \u2013 \u201eWie wir die Datenbank einrichten\u201c.<br \/>\n<b>Punkt 4<\/b>- Der Auftraggeber, der all diese Pracht von Grafiken und Zahlen sieht, ist in den kindlichen naiven \u00dcberzeugung, dass jetzt alles bei uns bald funktionieren wird. Und er gibt leicht und schmerzlos seine Geldressourcen aus. Das Management ist ebenfalls \u00fcberzeugt \u2013 unsere Ingenieure arbeiten gro\u00dfartig. Die Auslastung auf dem Maximum. <br \/>\n<b>Punkt 5<\/b>- Punkt 1 regelm\u00e4\u00dfig wiederholen.<br \/>\n<b class=\"spoiler_title\">Pfeffern\u00fcsse und Krapfen, blaue Flecken und Beulen<\/b><b>Pfeffern\u00fcsse und Krapfen: <\/b><br \/>\n1. Das Leben der Manager und Ingenieure ist einfach, vorhersehbar und voller Aktivit\u00e4t. Alles summt, alle sind besch\u00e4ftigt. <br \/>\n2. Das Leben des Auftraggebers ist auch nicht schlecht \u2013 er ist sich immer sicher, dass es nur ein bisschen Geduld braucht und alles sich regeln wird. Klappt es nicht, na ja, was soll\u2019s \u2013 diese Welt ist ungerecht, im n\u00e4chsten Leben wird es besser.<br \/>\n<b>Blaue Flecken und Beulen:<\/b><br \/>\n1. Fr\u00fcher oder sp\u00e4ter wird es einen schnelleren Anbieter f\u00fcr einen \u00e4hnlichen Service geben, der das Gleiche ein bisschen g\u00fcnstiger macht. Und wenn das Ergebnis dasselbe ist, warum mehr bezahlen? Das wird wiederum zur Abwanderung f\u00fchren.<br \/>\n2. Es ist langweilig. So langweilig wie jede wenig sinnvolle Aktivit\u00e4t.<br \/>\n3. Wie im vorherigen Fall gibt es keine Entwicklung. Aber f\u00fcr den Ingenieur ist der Nachteil, dass hier im Unterschied zur ersten Option st\u00e4ndig eine Datenbasis generiert werden muss. Und das kostet Zeit. Die man f\u00fcr sich selbst sinnvoll nutzen k\u00f6nnte. Denn wenn man sich nicht selbst um sich k\u00fcmmert, interessiert es niemanden.<\/p>\n<h3>Option 3 - Man muss nicht das Rad neu erfinden, man sollte es kaufen und fahren.<\/h3>\n<p>\nDie Ingenieure anderer Unternehmen essen nicht ohne Grund Pizza mit Bier (ah, die guten Zeiten in St. Petersburg in den 90ern). Lassen Sie uns \u00dcberwachungssysteme nutzen, die entwickelt, abgestimmt und einsatzbereit sind und tats\u00e4chlich einen Nutzen bringen (mindestens f\u00fcr ihre Entwickler).<br \/>\n<b class=\"spoiler_title\">Pfeffern\u00fcsse und Krapfen, blaue Flecken und Beulen<\/b><b>Pfeffern\u00fcsse und Krapfen:<\/b><br \/>\n1. Man muss keine Zeit mit dem Erfinden von Dingen verschwenden, die bereits erfunden sind. Nimm und nutze sie.<br \/>\n2. \u00dcberwachungssysteme werden nicht von Dummk\u00f6pfen entwickelt, und sie sind nat\u00fcrlich n\u00fctzlich.<br \/>\n3. Funktionierende \u00dcberwachungssysteme liefern in der Regel n\u00fctzliche gefilterte Informationen. <br \/>\n<b>Blaue Flecken und Beulen:<\/b><br \/>\n1. Der Ingenieur ist in diesem Fall kein Ingenieur, sondern lediglich ein Nutzer eines fremden Produkts. Oder ein User.<br \/>\n2. Der Kunde muss davon \u00fcberzeugt werden, etwas zu kaufen, wovon er im Grunde genommen keine Ahnung hat, und das sollte er auch nicht, und das Budget f\u00fcr das Jahr ist genehmigt und wird sich nicht \u00e4ndern. Dann muss man separate Ressourcen bereitstellen und diese auf das spezifische System einrichten. Das bedeutet, zuerst muss man bezahlen, zahlen und noch einmal zahlen. Und der Kunde ist geizig. Das ist die Norm in diesem Leben.<\/p>\n<h2>Was tun - Tschernyschewski? Deine Frage ist durchaus berechtigt. (c)<\/h2>\n<p>\nIn diesem konkreten Fall und der entstandenen Situation kann man es ein bisschen anders angehen - <b>Lassen Sie uns unser eigenes \u00dcberwachungssystem erstellen. <\/b><br \/>\n<img decoding=\"async\" alt=\"\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 - Reporting\" src=\"\/wp-content\/uploads\/2019\/04\/b59a3ad9e16b68c0fbc962a61d571c52.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nNun, nicht wirklich ein System im vollen Sinne des Wortes, das w\u00e4re zu hochtrabend und \u00fcberheblich gesagt, aber dennoch sich selbst die Aufgabe erleichtern und mehr Informationen zur L\u00f6sung von Leistungsproblemen sammeln. Um nicht in die Situation zu kommen - \"geh dorthin, wo du nicht wei\u00dft, und finde das, was du nicht wei\u00dft.\"<\/p>\n<h4>Was sind die Vor- und Nachteile dieser Option:<\/h4>\n<p><b>Vorteile:<\/b><br \/>\n1. Es ist interessant. Nun, mindestens interessanter als die st\u00e4ndigen \"shrink datafile, alter tablespace, usw.\" <br \/>\n2. Das sind neue F\u00e4higkeiten und neue Entwicklungen. Was perspektivisch fr\u00fcher oder sp\u00e4ter geb\u00fchrende Belohnungen und Leckereien bringen wird.<br \/>\n<b>Nachteile:<\/b><br \/>\n1. Man wird arbeiten m\u00fcssen. Viel arbeiten. <br \/>\n2. Man wird regelm\u00e4\u00dfig den Sinn und die Perspektiven der gesamten Aktivit\u00e4ten erkl\u00e4ren m\u00fcssen.<br \/>\n3. Auf etwas wird man ein Opfer bringen m\u00fcssen, denn die einzige verf\u00fcgbare Ressource f\u00fcr den Ingenieur \u2013 die Zeit \u2013 ist im Universum begrenzt. <br \/>\n<b>4. Das Schlimmste und Unangenehmste<\/b> \u2014 k\u00f6nnte ein Ergebnis hervorrufen, das wie \u201eweder ein M\u00e4uschen noch ein Frosch, sondern ein unbekanntes Tier\u201c aussieht.<\/p>\n<p><b>Wer nicht wagt, der nicht gewinnt.<\/b><br \/>\nSo \u2014 jetzt beginnt das Interessanteste.<\/p>\n<h2>Die allgemeine Idee \u2014 schematisch<\/h2>\n<p>\n<img decoding=\"async\" alt=\"\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 - Reporting\" src=\"\/wp-content\/uploads\/2019\/04\/d1ae2ddc1d4c43353fe93eebdaa8b81a.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n(<i>Die Abbildung stammt aus einem Artikel<\/i> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/444988\/\">\ud83e\udd47Wir begr\u00fc\u00dfen den Service von Cloudflare an den Adressen 1.1.1.1 und 1.0.0.1, oder \"das Angebot \u00f6ffentlicher DNS ist gewachsen!\" | ProHoster<\/a><\/noindex>\u00bb)<\/p>\n<p>Erl\u00e4uterung:<\/p>\n<ul>\n<li> In der Ziel-Datenbank wird die Standarderweiterung PostgreSQL \u2014 \u201epg_stat_statements\u201c installiert. <\/li>\n<li>In der \u00dcberwachungsdatenbank erstellen wir einen Satz von Servicetabellen zur Speicherung der Geschichte von pg_stat_statements in der Anfangsphase sowie zur Konfiguration von Metriken und zur \u00dcberwachung in der Zukunft.<\/li>\n<li> Auf dem \u00dcberwachungs-Host erstellen wir eine Reihe von Bash-Skripten, unter anderem zur Generierung von Vorf\u00e4llen im Ticket-System. <\/li>\n<\/ul>\n<h2>Servicetabellen<\/h2>\n<p>\nF\u00fcr den Anfang eine schematisch vereinfachte ERD, was letztendlich herausgekommen ist:<br \/>\n<img decoding=\"async\" alt=\"\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 - Reporting\" src=\"\/wp-content\/uploads\/2019\/04\/03d29f4d6932d470d9d88651cbf0c715.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<b class=\"spoiler_title\">Kurze Beschreibung der Tabellen<\/b><b>endpoint <\/b> \u2014 Host, Verbindungspunkt zum Instance<br \/>\n<b>database <\/b> \u2014 Datenbankparameter<br \/>\n<b>pg_stat_history <\/b> \u2014 Historische Tabelle zur Speicherung tempor\u00e4rer Snapshots der Darstellung von pg_stat_statements f\u00fcr die Ziel-Datenbank<br \/>\n<b>metric_glossary <\/b> \u2014 Glossar der Leistungsmetriken<br \/>\n<b>metric_config <\/b> \u2014 Konfiguration einzelner Metriken<br \/>\n<b>metric <\/b> \u2014 Konkrete Metrik f\u00fcr die \u00fcberwachte Anfrage<br \/>\n<b>metric_alert_history <\/b> \u2014 Geschichte der Warnungen zur Leistungs\u00fcberwachung<br \/>\n<b>log_query <\/b> \u2014 Systemtabelle zur Speicherung der analysierten Eintr\u00e4ge aus dem Protokoll der PostgreSQL-Datei, die von AWS geladen wird<br \/>\n<b>baseline <\/b> \u2014 Parameter des Zeitraum, der als Basis verwendet wird <br \/>\n<b>checkpoint <\/b> \u2014 Konfiguration der Metriken zur \u00dcberpr\u00fcfung des Datenbankzustands<br \/>\n<b>checkpoint_alert_history <\/b> \u2014 Geschichte der Warnungen f\u00fcr Metriken zur \u00dcberpr\u00fcfung des Datenbankzustands<br \/>\n<b>pg_stat_db_queries <\/b> \u2014 Systemtabelle aktiver Anfragen <br \/>\n<b>activity_log <\/b> \u2014 Systemtabelle des Aktivit\u00e4tsprotokolls <br \/>\n<b>trap_oid <\/b> \u2014 Systemtabelle zur Konfiguration von Fallstricken<\/p>\n<p><\/p>\n<h2>Schritt 1 \u2014 Sammeln von Leistungsstatistiken und Erhalt von Berichten<\/h2>\n<p>\nZur Speicherung der Leistungsstatistiken dient die Tabelle <b>pg_stat_history<\/b><br \/>\n<b class=\"spoiler_title\">Die Struktur der Tabelle pg_stat_history<\/b><\/p>\n<pre>\n                                          Tabelle \"public.pg_stat_history\"\n       Spalte        |            Typ             |                          Modifikatoren\n---------------------+-----------------------------+-------------------------------------------\n id                  | ganzzahlig                  | nicht null Standard nextval('pg_stat_history_id_seq'::regclass)\n snapshot_timestamp  | Zeitstempel ohne Zeitzone  |\n database_id         | ganzzahlig                  |\n dbid                | oid                         |\n userid              | oid                         |\n queryid             | bigint                      |\n query               | Text                        |\n calls               | bigint                      |\n total_time          | doppelte Pr\u00e4zision          |\n min_time            | doppelte Pr\u00e4zision          |\n max_time            | doppelte Pr\u00e4zision          |\n mean_time           | doppelte Pr\u00e4zision          |\n stddev_time         | doppelte Pr\u00e4zision          |\n rows                | bigint                      |\n shared_blks_hit     | bigint                      |\n shared_blks_read    | bigint                      |\n shared_blks_dirtied | bigint                      |\n shared_blks_written | bigint                      |\n local_blks_hit      | bigint                      |\n local_blks_read     | bigint                      |\n local_blks_dirtied  | bigint                      |\n local_blks_written  | bigint                      |\n temp_blks_read      | bigint                      |\n temp_blks_written   | bigint                      |\n blk_read_time       | doppelte Pr\u00e4zision          |\n blk_write_time      | doppelte Pr\u00e4zision          |\n baseline_id         | ganzzahlig                  |\nIndizes:\n    \"pg_stat_history_pkey\" PRIMARY KEY, btree (id)\n    \"database_idx\" btree (database_id)\n    \"queryid_idx\" btree (queryid)\n    \"snapshot_timestamp_idx\" btree (snapshot_timestamp)\nFremdschl\u00fcsselbeschr\u00e4nkungen:\n    \"database_id_fk\" FOREIGN KEY (database_id) REFERENCES database(id) ON DELETE CASCADE<\/pre>\n<p>\nWie man sieht, stellt die Tabelle lediglich kumulierte Daten der Ansicht dar <b>pg_stat_statements <\/b> in der Ziel-Datenbank.<\/p>\n<h3>Die Verwendung dieser Tabelle ist sehr einfach<\/h3>\n<p>\n<b>pg_stat_history<\/b> und wird die akkumulierten Statistiken \u00fcber die Ausf\u00fchrung von Abfragen f\u00fcr jede Stunde darstellen. Zu Beginn jeder Stunde, nach dem Ausf\u00fcllen der Tabelle, werden die Statistiken <b>pg_stat_statements<\/b> mit Hilfe von <b>pg_stat_statements_reset()<\/b>.<br \/>\nHinweis: <i>gesammelt, wobei die Statistiken f\u00fcr Abfragen mit einer Ausf\u00fchrungsdauer von mehr als 1 Sekunde erfasst werden.<\/i><br \/>\n<b class=\"spoiler_title\">Das Ausf\u00fcllen der Tabelle pg_stat_history<\/b><\/p>\n<pre><code class=\"plaintext\">--pg_stat_history.sql\nCREATE OR REPLACE FUNCTION pg_stat_history( ) RETURNS boolean AS $$\nDECLARE\n  endpoint_rec record ;\n  database_rec record ;\n  pg_stat_snapshot record ;\n  current_snapshot_timestamp timestamp without time zone;\nBEGIN\n  current_snapshot_timestamp = date_trunc('minute',now());  \n  \n  FOR endpoint_rec IN SELECT * FROM endpoint \n  LOOP\n    FOR database_rec IN SELECT * FROM database WHERE endpoint_id = endpoint_rec.id \n\t  LOOP\n\t    \n\t\tRAISE NOTICE 'NEUES SHAPSHOT WIRD ERSTELLT';\n\t\t\n\t\t--Verbinden mit der Ziel-Datenbank\t  \n\t    EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||endpoint_rec.host||' dbname='||database_rec.name||' user=USER password=PASSWORD '')';\n \n        RAISE NOTICE 'host % und dbname % ',endpoint_rec.host,database_rec.name;\n\t\tRAISE NOTICE 'Erstelle Snapshot von pg_stat_statements f\u00fcr Datenbank %',database_rec.name;\n\t\t\n\t\tSELECT \n\t      *\n\t\tINTO \n\t\t  pg_stat_snapshot\n\t    FROM dblink('LINK1',\n\t      'SELECT \n\t       dbid , SUM(calls),SUM(total_time),SUM(rows) ,SUM(shared_blks_hit) ,SUM(shared_blks_read) ,SUM(shared_blks_dirtied) ,SUM(shared_blks_written) , \n           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)\n\t       FROM pg_stat_statements WHERE dbid=(SELECT oid from pg_database where datname=current_database() ) \n\t\t   GROUP BY dbid\n  \t      '\n\t               )\n\t      AS t\n\t       ( dbid oid , calls bigint , \n  \t         total_time double precision , \n\t         rows bigint , shared_blks_hit bigint , shared_blks_read bigint ,shared_blks_dirtied bigint ,shared_blks_written\t bigint ,\n             local_blks_hit\t bigint ,local_blks_read bigint , local_blks_dirtied bigint ,local_blks_written bigint ,\n             temp_blks_read\t bigint ,temp_blks_written bigint ,\n             blk_read_time double precision , blk_write_time double precision\t  \n\t       );\n\t\t \n\t\tINSERT INTO pg_stat_history\n          ( \n\t\t    snapshot_timestamp  ,database_id  ,\n\t\t\tdbid , calls  ,total_time ,\n            rows ,shared_blks_hit  ,shared_blks_read  ,shared_blks_dirtied  ,shared_blks_written ,local_blks_hit , \t \t\n            local_blks_read,local_blks_dirtied,local_blks_written,temp_blks_read,temp_blks_written, \t\n            blk_read_time, blk_write_time \n\t\t  )\t\t  \n\t    VALUES\n\t      (\n\t       current_snapshot_timestamp ,\n\t\t   database_rec.id ,\n\t       pg_stat_snapshot.dbid ,pg_stat_snapshot.calls,\n\t       pg_stat_snapshot.total_time,\n\t       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 , \n           pg_stat_snapshot.local_blks_hit , pg_stat_snapshot.local_blks_read , pg_stat_snapshot.local_blks_dirtied , pg_stat_snapshot.local_blks_written , \n\t       pg_stat_snapshot.temp_blks_read , pg_stat_snapshot.temp_blks_written , pg_stat_snapshot.blk_read_time , pg_stat_snapshot.blk_write_time \t   \n\t      );\t\t   \n\t\t  \n        RAISE NOTICE 'Erstelle Snapshot von pg_stat_statements f\u00fcr Abfragen mit min_time mehr als 1000ms';\n\t\n        FOR pg_stat_snapshot IN\n          --Alle Abfragen mit max_time gr\u00f6\u00dfer als 1000 ms\n\t      SELECT \n\t        *\n\t      FROM dblink('LINK1',\n\t        'SELECT \n\t         dbid , userid ,queryid,query,calls,total_time,min_time ,max_time,mean_time, stddev_time ,rows ,shared_blks_hit ,\n\t\t\t shared_blks_read ,shared_blks_dirtied ,shared_blks_written , \n             local_blks_hit , local_blks_read , local_blks_dirtied , \n\t\t\t local_blks_written , temp_blks_read , temp_blks_written , blk_read_time , \n\t\t\t blk_write_time\n\t         FROM pg_stat_statements \n\t\t\t WHERE dbid=(SELECT oid from pg_database where datname=current_database() AND min_time &gt;= 1000 ) \n  \t        '\n\n\t                  )\n\t        AS t\n\t         ( dbid oid , userid oid , queryid bigint ,query text , calls bigint , \n  \t           total_time double precision ,min_time double precision\t ,max_time double precision\t , mean_time double precision\t ,  stddev_time double precision\t , \n\t           rows bigint , shared_blks_hit bigint , shared_blks_read bigint ,shared_blks_dirtied bigint ,shared_blks_written\t bigint ,\n               local_blks_hit\t bigint ,local_blks_read bigint , local_blks_dirtied bigint ,local_blks_written bigint ,\n               temp_blks_read\t bigint ,temp_blks_written bigint ,\n               blk_read_time double precision , blk_write_time double precision\t  \n\t         )\n\t    LOOP\n\t\t  INSERT INTO pg_stat_history\n          ( \n\t\t    snapshot_timestamp  ,database_id  ,\n\t\t\tdbid ,userid  , queryid  , query  , calls  ,total_time ,min_time ,max_time ,mean_time ,stddev_time ,\n            rows ,shared_blks_hit  ,shared_blks_read  ,shared_blks_dirtied  ,shared_blks_written ,local_blks_hit , \t \t\n            local_blks_read,local_blks_dirtied,local_blks_written,temp_blks_read,temp_blks_written, \t\n            blk_read_time, blk_write_time \n\t\t  )\t\t  \n\t      VALUES\n\t      (\n\t       current_snapshot_timestamp ,\n\t\t   database_rec.id ,\n\t       pg_stat_snapshot.dbid ,pg_stat_snapshot.userid ,pg_stat_snapshot.queryid,pg_stat_snapshot.query,pg_stat_snapshot.calls,\n\t       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 ,\n\t       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 , \n           pg_stat_snapshot.local_blks_hit , pg_stat_snapshot.local_blks_read , pg_stat_snapshot.local_blks_dirtied , pg_stat_snapshot.local_blks_written , \n\t       pg_stat_snapshot.temp_blks_read , pg_stat_snapshot.temp_blks_written , pg_stat_snapshot.blk_read_time , pg_stat_snapshot.blk_write_time \t   \n\t      );\n\t\t  \n        END LOOP;\n\n        PERFORM dblink_disconnect('LINK1');  \n\t\t\t\t\n\t  END LOOP ;--FOR database_rec IN SELECT * FROM database WHERE endpoint_id = endpoint_rec.id \n    \n  END LOOP;\n\nRETURN TRUE;  \nEND\n$$ LANGUAGE plpgsql;<\/code><\/pre>\n<p>In der Folge, nach einer gewissen Zeit in der Tabelle <b>pg_stat_history<\/b> werden wir eine Reihe von Aufnahmen des Inhalts der Tabelle haben <b>pg_stat_statements <\/b>der Ziel-Datenbank. <\/p>\n<h2>Eigentlich das Reporting<\/h2>\n<p>\nDurch einfache Abfragen lassen sich durchaus n\u00fctzliche und interessante Berichte generieren.<\/p>\n<h2>Aggregierte Daten f\u00fcr den angegebenen Zeitraum<\/h2>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  database_id , \n  SUM(calls) AS calls ,SUM(total_time)  AS total_time ,\n  SUM(rows) AS rows , SUM(shared_blks_hit)  AS shared_blks_hit,\n  SUM(shared_blks_read) AS shared_blks_read ,\n  SUM(shared_blks_dirtied) AS shared_blks_dirtied,\n  SUM(shared_blks_written) AS shared_blks_written , \n  SUM(local_blks_hit) AS local_blks_hit , \n  SUM(local_blks_read) AS local_blks_read , \n  SUM(local_blks_dirtied) AS local_blks_dirtied , \n  SUM(local_blks_written)  AS local_blks_written,\n  SUM(temp_blks_read) AS temp_blks_read, \n  SUM(temp_blks_written) temp_blks_written , \n  SUM(blk_read_time) AS blk_read_time , \n  SUM(blk_write_time) AS blk_write_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NULL AND\n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nGROUP BY database_id ;<\/code><\/pre>\n<p><\/p>\n<h4>DB-Zeit<\/h4>\n<blockquote><p>to_char(interval '1 Millisekunde' * pg_total_stat_history_rec.total_time, 'HH24:MI:SS.MS')<\/p><\/blockquote>\n<p><\/p>\n<h4>I\/O-Zeit<\/h4>\n<blockquote><p>to_char(interval '1 Millisekunde' * (pg_total_stat_history_rec.blk_read_time + pg_total_stat_history_rec.blk_write_time), 'HH24:MI:SS.MS')<\/p><\/blockquote>\n<h3>TOP10 SQL nach total_time<\/h3>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  queryid , \n  SUM(calls) AS calls ,\n  SUM(total_time)  AS total_time  \t\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT \nGROUP BY queryid \nORDER BY 3 DESC \nLIMIT 10<\/code><\/pre>\n<pre>-------------------------------------------------------------------------------------\n| TOP10 SQL NACH DER TOTALEN AUSF\u00dcHRUNGSZEIT\n|   #|    queryid|      calls|    calls %|                total_time (ms) |  dbtime %\n+----+-----------+-----------+-----------+--------------------------------+----------\n|   1|  821760255|          2|     .00001|00:03:23.141(    203141.681 ms.)|      5.42\n|   2| 4152624390|          2|     .00001|00:03:13.929(    193929.215 ms.)|      5.17\n|   3| 1484454471|          4|     .00001|00:02:09.129(    129129.057 ms.)|      3.44\n|   4|  655729273|          1|     .00000|00:02:01.869(    121869.981 ms.)|      3.25\n|   5| 2460318461|          1|     .00000|00:01:33.113(     93113.835 ms.)|      2.48\n|   6| 2194493487|          4|     .00001|00:00:17.377(     17377.868 ms.)|       .46\n|   7| 1053044345|          1|     .00000|00:00:06.156(      6156.352 ms.)|       .16\n|   8| 3644780286|          1|     .00000|00:00:01.063(      1063.830 ms.)|       .03\n<\/pre>\n<h4>TOP10 SQL nach der gesamten I\/O-Zeit<\/h4>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  queryid , \n  SUM(calls) AS calls ,\n  SUM(blk_read_time + blk_write_time)  AS io_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nGROUP BY  queryid \nORDER BY 3 DESC \nLIMIT 10<\/code><\/pre>\n<pre>----------------------------------------------------------------------------------------\n| TOP10 SQL NACH GESAMT I\/O ZEIT\n|   #|    queryid|      aufrufe|    aufrufe %|                   I\/O zeit (ms)|db I\/O zeit %\n+----+-----------+-----------+-----------+--------------------------------+-------------\n|   1| 4152624390|          2|     .00001|00:08:31.616(    511616.592 ms.)|        31.06\n|   2|  821760255|          2|     .00001|00:08:27.099(    507099.036 ms.)|        30.78\n|   3|  655729273|          1|     .00000|00:05:02.209(    302209.137 ms.)|        18.35\n|   4| 2460318461|          1|     .00000|00:04:05.981(    245981.117 ms.)|        14.93\n|   5| 1484454471|          4|     .00001|00:00:39.144(     39144.221 ms.)|         2.38\n|   6| 2194493487|          4|     .00001|00:00:18.182(     18182.816 ms.)|         1.10\n|   7| 1053044345|          1|     .00000|00:00:16.611(     16611.722 ms.)|         1.01\n|   8| 3644780286|          1|     .00000|00:00:00.436(       436.205 ms.)|          .03\n<\/pre>\n<h4>TOP10 SQL nach max. Ausf\u00fchrungszeit<\/h4>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  id AS snapshotid , \n  queryid , \n  snapshot_timestamp ,  \n  max_time \nFROM \n  pg_stat_history \nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nORDER BY 4 DESC \nLIMIT 10<\/code><\/pre>\n<p><\/p>\n<pre>-----------------------------------------------------------------------------------------\n| TOP10 SQL NACH MAX AUSF\u00dcHRUNGSZEIT\n|   #|          snapshot| snapshotID|    queryid|                           max_time (ms)\n+----+------------------+-----------+-----------+----------------------------------------\n|   1|  05.04.2019 01:03|       4169|  655729273|        00:02:01.869(    121869.981 ms.)\n|   2|  04.04.2019 17:00|       4153|  821760255|        00:01:41.570(    101570.841 ms.)\n|   3|  04.04.2019 16:00|       4146|  821760255|        00:01:41.570(    101570.841 ms.)\n|   4|  04.04.2019 16:00|       4144| 4152624390|        00:01:36.964(     96964.607 ms.)\n|   5|  04.04.2019 17:00|       4151| 4152624390|        00:01:36.964(     96964.607 ms.)\n|   6|  05.04.2019 10:00|       4188| 1484454471|        00:01:33.452(     93452.150 ms.)\n|   7|  04.04.2019 17:00|       4150| 2460318461|        00:01:33.113(     93113.835 ms.)\n|   8|  04.04.2019 15:00|       4140| 1484454471|        00:00:11.892(     11892.302 ms.)\n|   9|  04.04.2019 16:00|       4145| 1484454471|        00:00:11.892(     11892.302 ms.)\n|  10|  04.04.2019 17:00|       4152| 1484454471|        00:00:11.892(     11892.302 ms.)\n<\/pre>\n<h4>TOP10 SQL nach SHARED Puffer lesen\/schreiben<\/h4>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  id AS snapshotid , \n  queryid ,\n  snapshot_timestamp , \n  shared_blks_read , \n  shared_blks_written \nFROM \n  pg_stat_history\nWHERE \n  queryid IS NOT NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND\n  ( shared_blks_read &gt; 0 OR shared_blks_written &gt; 0 )\nORDER BY 4 DESC  , 5 DESC \nLIMIT 10<\/code><\/pre>\n<pre>--------------------------------------------------------------------------------------------\n| TOP10 SQL NACH GETEILTEN BUFFERLESEN\/ -SCHREIBEN\n|   #|          Schnappschuss| SchnappschussID|    AbfrageID|   geteilt gelesene Bl\u00f6cke|  geteilt geschriebene Bl\u00f6cke\n+----+------------------+-----------+-----------+---------------------+---------------------\n|   1|  04.04.2019 17:00|       4153|  821760255|               797308|                    0\n|   2|  04.04.2019 16:00|       4146|  821760255|               797308|                    0\n|   3|  05.04.2019 01:03|       4169|  655729273|               797158|                    0\n|   4|  04.04.2019 16:00|       4144| 4152624390|               756514|                    0\n|   5|  04.04.2019 17:00|       4151| 4152624390|               756514|                    0\n|   6|  04.04.2019 17:00|       4150| 2460318461|               734117|                    0\n|   7|  04.04.2019 17:00|       4155| 3644780286|                52973|                    0\n|   8|  05.04.2019 01:03|       4168| 1053044345|                52818|                    0\n|   9|  04.04.2019 15:00|       4141| 2194493487|                52813|                    0\n|  10|  04.04.2019 16:00|       4147| 2194493487|                52813|                    0\n--------------------------------------------------------------------------------------------\n<\/pre>\n<h4>Histogramm der Verteilung der Abfragen nach maximaler Ausf\u00fchrungszeit<\/h4>\n<p><b class=\"spoiler_title\">Anfragen<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT  \n  MIN(max_time) AS hist_min  , \n  MAX(max_time) AS hist_max , \n  (( MAX(max_time) - MIN(min_time) ) \/ hist_columns ) as hist_width\nFROM \n  pg_stat_history \nWHERE \n  queryid IS NOT NULL AND\n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT ;\n\nSELECT \n  SUM(calls) AS calls\nFROM \n  pg_stat_history \nWHERE \n  queryid IS NOT NULL AND\n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND \n  ( max_time &gt;= hist_current_min AND  max_time &lt; hist_current_max ) ;\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| MAX_TIME-HISTOGRAMM\n| ANZAHL DER ABFRAGEN : 33851920\n| MINDAUER  : 00:00:01.063\n| MAXDAUER  : 00:02:01.869\n---------------------------------------------------------------------------------\n|                      min Dauer|                      max Dauer|     Aufrufe\n+----------------------------------+----------------------------------+----------\n| 00:00:01.063(      1063.830 ms.) | 00:00:13.144(     13144.445 ms.) | 9\n| 00:00:13.144(     13144.445 ms.) | 00:00:25.225(     25225.060 ms.) | 0\n| 00:00:25.225(     25225.060 ms.) | 00:00:37.305(     37305.675 ms.) | 0\n| 00:00:37.305(     37305.675 ms.) | 00:00:49.386(     49386.290 ms.) | 0\n| 00:00:49.386(     49386.290 ms.) | 00:01:01.466(     61466.906 ms.) | 0\n| 00:01:01.466(     61466.906 ms.) | 00:01:13.547(     73547.521 ms.) | 0\n| 00:01:13.547(     73547.521 ms.) | 00:01:25.628(     85628.136 ms.) | 0\n| 00:01:25.628(     85628.136 ms.) | 00:01:37.708(     97708.751 ms.) | 4\n| 00:01:37.708(     97708.751 ms.) | 00:01:49.789(    109789.366 ms.) | 2\n| 00:01:49.789(    109789.366 ms.) | 00:02:01.869(    121869.981 ms.) | 0\n<\/pre>\n<h4>TOP10 Schnappsch\u00fcsse nach Abfrage pro Sekunde<\/h4>\n<p><b class=\"spoiler_title\">Anfragen<\/b><\/p>\n<pre><code class=\"plaintext\">--pg_qps.sql\n--Berechnung der Abfragen pro Sekunde \nCREATE OR REPLACE FUNCTION pg_qps( pg_stat_history_id integer ) RETURNS double precision AS $$\nDECLARE\n pg_stat_history_rec record ;\n prev_pg_stat_history_id integer ;\n prev_pg_stat_history_rec record;\n total_seconds double precision ;\n result double precision;\nBEGIN \n  result = 0 ;\n  \n  SELECT *\n  INTO pg_stat_history_rec\n  FROM \n    pg_stat_history\n  WHERE id = pg_stat_history_id ;\n\n  IF pg_stat_history_rec.snapshot_timestamp IS NULL \n  THEN\n    RAISE EXCEPTION 'FEHLER - pg_stat_history f\u00fcr id = % nicht gefunden',pg_stat_history_id;\n  END IF ;  \n  \n --RAISE NOTICE 'pg_stat_history_id = % , snapshot_timestamp = %', pg_stat_history_id , \n pg_stat_history_rec.snapshot_timestamp ;\n  \n  SELECT \n    MAX(id)   \n  INTO\n    prev_pg_stat_history_id\n  FROM\n    pg_stat_history\n  WHERE \n    database_id = pg_stat_history_rec.database_id AND\n\tqueryid IS NULL AND\n\tid  0 \n  THEN\n    result = pg_stat_history_rec.calls \/ total_seconds ;\n  ELSE\n   result = 0 ; \n  END IF;\n   \n RETURN result ;\nEND\n$$ LANGUAGE plpgsql;\n\n\nSELECT \n  id , \n  snapshot_timestamp ,\n  calls , \t\n  total_time , \n  ( select pg_qps( id )) AS QPS ,\n  blk_read_time ,\n  blk_write_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT AND\n  ( select pg_qps( id )) IS NOT NULL \nORDER BY 5 DESC \nLIMIT 10\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| TOP10 Schnappsch\u00fcsse, geordnet nach QueryPerSeconds-Zahlen\n-----------------------------------------------------------------------------------------------------------------------------------------------\n|    #|          Schnappschuss| snapshotID|      Aufrufe|                      Gesamte db-Zeit|        QPS|                          I\/O-Zeit| I\/O-Zeit %\n+-----+------------------+-----------+-----------+----------------------------------+-----------+----------------------------------+-----------\n|    1|  04.04.2019 20:04|       4161|    5758631|  00:06:30.513(    390513.926 ms.)|   1573.396|  00:00:01.470(      1470.110 ms.)|       .376\n|    2|  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\n|    3|  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\n|    4|  04.04.2019 21:03|       4163|    2781536|  00:03:06.470(    186470.979 ms.)|    785.745|  00:00:00.249(       249.865 ms.)|       .134\n|    5|  04.04.2019 19:03|       4159|    2890362|  00:03:16.784(    196784.755 ms.)|    776.979|  00:00:01.441(      1441.386 ms.)|       .732\n|    6|  04.04.2019 14:00|       4137|    2397326|  00:04:43.033(    283033.854 ms.)|    665.924|  00:00:00.024(        24.505 ms.)|       .009\n|    7|  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\n|    8|  04.04.2019 13:00|       4135|    2373043|  00:04:26.791(    266791.988 ms.)|    659.179|  00:00:00.064(        64.261 ms.)|       .024\n|    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\n|   10|  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\n<\/pre>\n<h4>St\u00fcndliche Ausf\u00fchrungsprotokolle mit QueryPerSeconds und I\/O-Zeit<\/h4>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">SELECT \n  id , \n  snapshot_timestamp ,\n  calls , \t\n  total_time , \n  ( select pg_qps( id )) AS QPS ,\n  blk_read_time ,\n  blk_write_time\nFROM \n  pg_stat_history\nWHERE \n  queryid IS NULL AND \n  database_id = DATABASE_ID  AND\n  snapshot_timestamp BETWEEN BEGIN_TIMEPOINT AND END_TIMEPOINT\nORDER BY 2\n<\/code><\/pre>\n<pre>|-----------------------------------------------------------------------------------------------\n| STUNDENWEISE AUSF\u00dcHRUNGSGESCHICHTE  MIT QueryPerSeconds und I\/O-Zeit\n-----------------------------------------------------------------------------------------------------------------------------------------------\n| ABFRAGEPROTOKOLL PRO SEKUNDE\n|    #|          Snapshot| SnapshotID|      Aufrufe|                      Gesamte DB-Zeit|        QPS|                          I\/O-Zeit| I\/O-Zeit %\n+-----+------------------+-----------+-----------+----------------------------------+-----------+----------------------------------+-----------\n|    1|  04.04.2019 11:00|       4131|       3747|  00:00:00.835(       835.374 ms.)|      1.041|  00:00:00.000(          .000 ms.)|       .000\n|    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\n|    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\n|    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\n|    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\n|    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\n|    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\n|    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\n|    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\n|   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\n|   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\n|   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\n|   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\n|   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\n|   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\n|   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\n|   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\n|   18|  05.04.2019 06:00|       4179|       3747|  00:00:00.849(       849.561 ms.)|      1.041|  00:00:00.000(          .051 ms.)|       .006\n|   19|  05.04.2019 07:00|       4181|       3747|  00:00:00.839(       839.416 ms.)|      1.041|  00:00:00.000(          .062 ms.)|       .007\n|   20|  05.04.2019 08:00|       4183|       3747|  00:00:00.846(       846.382 ms.)|      1.041|  00:00:00.000(          .007 ms.)|       .001\n|   21|  05.04.2019 09:00|       4185|       3747|  00:00:00.855(       855.426 ms.)|      1.041|  00:00:00.000(          .065 ms.)|       .008\n|   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\n<\/pre>\n<h4>Text aller SQL-SELECTs<\/h4>\n<p><b class=\"spoiler_title\">Abfrage<\/b><\/p>\n<pre><code class=\"plaintext\">W\u00c4HLEN Sie \n  queryid , \n  query \nVON \n  pg_stat_history\nWO \n  queryid IST NICHT NULL UND \n  database_id = DATABASE_ID UND\n  snapshot_timestamp ZWISCHEN BEGIN_TIMEPOINT UND END_TIMEPOINT\nGRUPPEN NACH queryid , query\n<\/code><\/pre>\n<h2>Fazit<\/h2>\n<p>\nWie zu sehen ist, kann man mit recht einfachen Mitteln eine Menge n\u00fctzlicher Informationen \u00fcber die Auslastung und den Zustand der Datenbank erhalten. <\/p>\n<p><b>Anmerkung:<\/b>Wenn wir in den Abfragen queryid festhalten, erhalten wir die Historie f\u00fcr eine einzelne Abfrage (zum Zwecke der Platzersparnis sind die Berichte f\u00fcr einzelne Abfragen weggelassen).<\/p>\n<p>Damit liegen die statistischen Daten zur Leistungsf\u00e4higkeit der Abfragen vor und werden gesammelt.<br \/>\nDie erste Phase \u201eSammlung von statistischen Daten\u201c ist abgeschlossen.<\/p>\n<p>Wir k\u00f6nnen zur zweiten Phase \u00fcbergehen \u2013 \u201eEinstellung der Leistungsmetriken\u201c.<br \/>\n<img decoding=\"async\" alt=\"\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 - Reporting\" src=\"\/wp-content\/uploads\/2019\/04\/a893e49280d4cb425e4667a5c51d2397.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<b>Aber das ist eine ganz andere Geschichte.<\/b><\/p>\n<p><i>Fortsetzung folgt\u2026<\/i><br \/>\n<br \/>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/icl_services\/blog\/446734\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b. \u0418\u043b\u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043e \u0442\u043e\u043c, \u0437\u0430\u0447\u0435\u043c \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0443 \u0431\u0430\u0437 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0442\u044c \u0441\u0432\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0441\u043a\u043e\u0435 \u043f\u0440\u043e\u0448\u043b\u043e\u0435. \u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435 \u0412\u0441\u0435 \u0438\u043c\u0435\u043d\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b. \u0421\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b. \u041c\u0430\u0442\u0435\u0440\u0438\u0430\u043b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438\u0447\u043d\u043e\u0435 \u043c\u043d\u0435\u043d\u0438\u0435 \u0430\u0432\u0442\u043e\u0440\u0430. Disclaimer of warranties: \u0432 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u0435\u043c\u043e\u043c \u0446\u0438\u043a\u043b\u0435 \u0441\u0442\u0430\u0442\u0435\u0439 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0445 \u0442\u0430\u0431\u043b\u0438\u0446 \u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24168,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32353","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 PostgreSQL. \u0427\u0430\u0441\u0442\u044c 1 \u2014 \u0440\u0435\u043f\u043e\u0440\u0442\u0438\u043d\u0433 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:46:32+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:46:32+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47\u00dcberwachung der Leistungsf\u00e4higkeit von PostgreSQL-Abfragen. Teil 1 \u2013 Reporting | ProHoster","description":"Ingenieur \u2013 \u00fcbersetzt aus dem Lateinischen \u2013 inspiriert. Ein Ingenieur kann alles. (c) R.Diesel. Epigraphen.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 PostgreSQL. \u0427\u0430\u0441\u0442\u044c 1 \u2014 \u0440\u0435\u043f\u043e\u0440\u0442\u0438\u043d\u0433 | ProHoster","og:description":"\u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u2014 \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0441 \u043b\u0430\u0442\u044b\u043d\u0438 \u2014 \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u0435\u043d\u043d\u044b\u0439. \u0418\u043d\u0436\u0435\u043d\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0451. (\u0441) \u0420.\u0414\u0438\u0437\u0435\u043b\u044c. \u042d\u043f\u0438\u0433\u0440\u0430\u0444\u044b.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/monitoring-proizvoditelnosti-zaprosov-postgresql-chast-1-reporting","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:46:32+00:00","article:modified_time":"2019-10-31T18:46:32+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32353","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 10:28:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:13:42","updated":"2026-01-21 10:28:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/32353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=32353"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/32353\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/24168"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=32353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=32353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=32353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}