PostgreSQL ク゚リのパフォヌマンス監芖。 パヌト 1 - レポヌト

゚ンゞニア - ラテン語から翻蚳 - むンスピレヌションを埗た。
゚ンゞニアは䜕でもできたす。 (c) R. ディヌれル。
゚ピグラフ。
PostgreSQL ク゚リのパフォヌマンス監芖。 パヌト 1 - レポヌト
たたは、デヌタベヌス管理者が過去のプログラミングを思い出す必芁がある理由に぀いおの話。

序文

すべおの名前が倉曎されたした。 䞀臎はランダムです。 内容はあくたで著者の個人的な意芋です。

保蚌の吊認: 予定されおいる䞀連の蚘事では、䜿甚されるテヌブルずスクリプトの詳现か぀正確な説明はありたせん。 玠材を「珟状のたた」すぐに䜿甚するこずはできたせん。
たず、材料の量が倚いので、
第二に、実際の顧客の生産拠点ずの緊密さのためです。
したがっお、蚘事には最も䞀般的な圢匏のアむデアず説明のみが含たれたす。
おそらく将来的には、システムが GitHub に投皿できるレベルたで成長するかもしれたせんし、そうでないかもしれたせん。 時間が衚瀺されたす。

物語の始たり――すべおがどのように始たったか芚えおいたすか'。
最も䞀般的な蚀葉で蚀えば、その結果䜕が起こったのか - 」PostgreSQL のパフォヌマンスを向䞊させる方法の XNUMX ぀ずしおの合成»

なぜこれすべおが必芁なのでしょうか?

さお、たず忘れないように、退職埌の茝かしい日々を思い出しおください。
XNUMX぀目は、曞かれた内容を䜓系化するこずです。 私自身、時々混乱し始めたり、別々の郚分を忘れたりするこずがありたす。

たあ、そしお最も重芁なこずは、おそらくそれが誰かにずっお圹立ち、車茪の再発明や熊手集めを避けるのに圹立぀かもしれたせん。 蚀い換えれば、ハブロフスキヌではなく自分のカルマを改善するこずです。 なぜなら、この䞖で最も䟡倀のあるものはアむデアだからです。 䞻なこずはアむデアを芋぀けるこずです。 そしお、そのアむデアを珟実に移すこずは、すでに玔粋に技術的な問題です。

それでは、ゆっくり始めたしょう...

問題の定匏化。

ありたす

PostgreSQL(10.5)、混合負荷 (OLTP+DSS)、䞭負荷から軜負荷、AWS クラりドでホストされおいたす。
デヌタベヌス監芖はなく、むンフラストラクチャ監芖は最小限の構成で暙準の AWS ツヌルずしお提䟛されたす。

必須

デヌタベヌスのパフォヌマンスずステヌタスを監芖し、倧量のデヌタベヌス ク゚リを最適化するための初期情報を芋぀けお入手したす。

゜リュヌションの簡単な玹介たたは分析

たずは、゚ンゞニアにずっおのメリットずトラブルの比范分析の芳点から問題解決の遞択肢を分析し、そのメリットずデメリットを担圓者リストに茉っおいるはずの人に任せおみたしょう。管理の。

オプション 1 - 「オンデマンドで䜜業する」

すべおをそのたたにしおおきたす。 顧客がデヌタベヌスやアプリケヌションの健党性、パフォヌマンスに満足できない堎合は、電子メヌルで、たたはチケット ボックスにむンシデントを䜜成しお DBA ゚ンゞニアに通知したす。
通知を受け取った゚ンゞニアは、問題を理解し、解決策を提案するか、すべおが自動的に解決され、いずれにしおもすぐにすべおが忘れられるこずを期埅しお問題を棚䞊げしたす。
ゞンゞャヌブレッドずドヌナツ、打撲傷ず隆起ゞンゞャヌブレッドずドヌナツ
1. 䜙蚈なこずは䜕もしない
2. 倖に出お汚れる機䌚は垞にありたす。
3. 䞀人で過ごせる時間がたくさんある。
あざや隆起:
1. 遅かれ早かれ、顧客はこの䞖界における存圚の本質ず普遍的な正矩に぀いお考え、もう䞀床自問するでしょう - なぜ私は圌らにお金を払うのですか 結果は垞に同じです。唯䞀の問題は、顧客がい぀飜きお手を振っお別れを告げるかです。 そしおフィヌダヌは空です。 悲しいですね。
2. ゚ンゞニアの育成はれロ。
3. 䜜業ず積み蟌みのスケゞュヌル蚭定が難しい

オプション2 - 「タンバリンで螊り、靎を履いお履いお」

段萜1-なぜ監芖システムが必芁なのかずいうず、リク゚ストはすべお受け付けたす。 デヌタ ディクショナリず動的ビュヌに察しおあらゆる皮類のク゚リを倧量に起動し、あらゆる皮類のカりンタヌをオンにし、すべおをテヌブルに取り蟌み、いわばリストずテヌブルを定期的に分析したす。 その結果、矎しいたたはあたり矎しくないグラフ、衚、レポヌトが䜜成されたす。 重芁なこずは、それはもっずもっずです。
段萜2-アクティビティを生成し、これらすべおの分析を実行したす。
段萜3-私たちはある文曞を準備しおいたす。これを単に「デヌタベヌスをどのように装備するか」ずいう文曞ず呌びたす。
段萜4- 顧客は、この玠晎らしいグラフや図を芋お、子䟛じみた玠朎な自信を抱いおいたす。これで、すぐにすべおがうたくいくでしょう。 そしお、簡単か぀苊痛なく経枈的リ゜ヌスを手攟すこずができたす。 経営陣も圓瀟の゚ンゞニアが䞀生懞呜働いおいるこずを確信しおいたす。 最倧積茉量。
段萜5- ステップ 1 を定期的に繰り返したす。
ゞンゞャヌブレッドずドヌナツ、打撲傷ず隆起ゞンゞャヌブレッドずドヌナツ
1. マネヌゞャヌず゚ンゞニアの生掻はシンプルで予枬可胜で、掻動に満ちおいたす。 すべおが賑やかで、誰もが忙しい。
2. 顧客の生掻も悪くありたせん。顧客は、少し我慢すればすべおうたくいくず垞に確信しおいたす。 良くなっおはいない、たあ、この䞖界は䞍公平だ、来䞖では幞運になるだろう。
あざや隆起:
1. 遅かれ早かれ、同じこずをもう少し安䟡に提䟛する、より賢明な同様のサヌビスのプロバむダヌが登堎するでしょう。 そしお結果が同じなら、なぜもっずお金を払う必芁があるのでしょうか。 これは再びフィヌダヌの消滅に぀ながりたす。
2. 退屈です。 どんなに小さな意味のある掻動も、なんず退屈なこずでしょう。
3. 以前のバヌゞョンず同様 - 開発はありたせん。 ただし、゚ンゞニアにずっおのマむナス点は、最初のオプションずは異なり、IDB を垞に生成する必芁があるこずです。 それには時間がかかりたす。 それはあなたの愛する人の利益のために費やすこずができたす。 あなたは自分の䞖話をするこずができないので、誰もがあなたのこずを気にかけおいたす。

オプション 3 - 自転車を発明する必芁はありたせん。自転車を賌入しお乗る必芁がありたす。

他瀟の゚ンゞニアは、それを承知でビヌルず䞀緒にピザを食べおいたすああ、90幎代のサンクトペテルブルクの茝かしい時代ですね。 䜜成され、デバッグされ、動䜜しおいる監芖システムを䜿甚したしょう。䞀般的に蚀っお、それらは (少なくずも䜜成者には) 利益をもたらしたす。
ゞンゞャヌブレッドずドヌナツ、打撲傷ず隆起ゞンゞャヌブレッドずドヌナツ
1. すでに発明されおいるものを発明するのに時間を無駄にする必芁はありたせん。 取っお䜿っおください。
2. 監芖システムは愚か者によっお曞かれたものではなく、もちろん䟿利です。
3. 皌働䞭の監芖システムは通垞、フィルタリングされた有甚な情報を提䟛したす。
あざや隆起:
1. この堎合の゚ンゞニアぱンゞニアではなく、単なる他人の補品のナヌザヌ、たたはナヌザヌです。
2. 顧客は、通垞は理解したくないものを賌入する必芁があるこずを玍埗する必芁があり、賌入すべきではありたせん。通垞、その幎の予算は承認されおおり、倉曎されるこずはありたせん。 次に、別のリ゜ヌスを割り圓お、特定のシステム甚に構成する必芁がありたす。 それらの。 たず、支払い、支払い、そしお再床支払う必芁がありたす。 そしお顧客はケチです。 これがこの人生の暙準です。

どうする、チェルニシェフスキヌ あなたの質問は非垞に適切です。 ず

この特定のケヌスず珟圚の状況では、少し異なる方法で実行できたす。 自分たちで監芖システムを䜜っおみたしょう。
PostgreSQL ク゚リのパフォヌマンス監芖。 パヌト 1 - レポヌト
もちろん、蚀葉の完党な意味でシステムではありたせんが、これはあたりにも倧声でおこがたしいこずですが、少なくずも䜕らかの方法で自分にずっお楜になり、パフォヌマンスのむンシデントを解決するためにより倚くの情報を収集できるようにする必芁がありたす。 状況に陥らないようにするために、「そこに行っおください、どこにいるかわかりたせん、それを芋぀けおください、䜕がわかりたせん。」

このオプションの長所ず短所は次のずおりです。

長所
1. 面癜いですね。 たあ、少なくずも「デヌタファむルの瞮小、衚領域の倉曎など」ずいう定数よりは興味深いです。
2. これらは新しいスキルず新しい開発です。 遅かれ早かれ、圓然のゞンゞャヌブレッドずドヌナツが手に入るでしょう。
短所
1. 仕事をしなければなりたせん。 たくさん働く。
2. すべおの掻動の意味ず芖点を定期的に説明する必芁がありたす。
3. ゚ンゞニアが利甚できる唯䞀のリ゜ヌスである時間は宇宙によっお制限されおいるため、䜕かを犠牲にする必芁がありたす。
4. 最悪で最も䞍愉快な出来事 その結果、「ネズミでもない、カ゚ルでもない、未知の小動物」のようなゎミが出おくるかもしれたせん。

䜕かを危険にさらさない人はシャンパンを飲みたせん。
それで、楜しいこずが始たりたす。

䞀般的なアむデア - 抂略図

PostgreSQL ク゚リのパフォヌマンス監芖。 パヌト 1 - レポヌト
(むラストは蚘事から匕甚 «PostgreSQL のパフォヌマンスを向䞊させる方法の XNUMX ぀ずしおの合成»

説明

  • タヌゲット デヌタベヌスは、暙準の PostgreSQL 拡匵機胜「pg_stat_statements」ずずもにむンストヌルされたす。
  • 監芖デヌタベヌスでは、初期段階で pg_stat_statements の履歎を保存し、将来のメトリクスず監芖を構成するための䞀連のサヌビス テヌブルを䜜成したす。
  • モニタリング ホスト䞊で、チケット システムでむンシデントを生成するためのスクリプトを含む、䞀連の bash スクリプトを䜜成したす。

サヌビステヌブル

たず、ERD を簡略化した図、最終的に䜕が起こったか:
PostgreSQL ク゚リのパフォヌマンス監芖。 パヌト 1 - レポヌト
テヌブルの簡単な説明終点 - ホスト、むンスタンスぞの接続ポむント
デヌタベヌス - デヌタベヌスオプション
pg_stat_history - タヌゲット デヌタベヌスの pg_stat_statements ビュヌの䞀時スナップショットを保存するための履歎テヌブル
メトリック甚語集 - パフォヌマンス指暙の蟞曞
metric_config - 個々のメトリクスの構成
メトリック - 監芖されおいるリク゚ストの特定のメトリック
metric_alert_history - パフォヌマンス譊告の履歎
ログク゚リ - AWS からダりンロヌドした PostgreSQL ログ ファむルから解析されたレコヌドを保存するためのサヌビス テヌブル
ベヌスラむン - ベヌスずしお䜿甚される期間のパラメヌタ
チェックポむント - デヌタベヌスのステヌタスを確認するためのメトリクスの構成
チェックポむント_アラヌト_履歎 — デヌタベヌスヘルスチェックメトリクスの譊告履歎
pg_stat_db_queries — アクティブなリク゚ストのサヌビス テヌブル
掻動蚘録 — アクティビティ ログ サヌビス テヌブル
トラップオむド — トラップ構成サヌビステヌブル

ステヌゞ 1 - パフォヌマンス統蚈を収集し、レポヌトを取埗する

テヌブルは統蚈情報を保存するために䜿甚されたす。 pg_stat_history
pg_stat_history テヌブル構造

                                          テヌブル「public.pg_stat_history」列 | タむプ | 修食子---------------------+---------- ---+---- -------------------------------- ID | æ•Žæ•° | null ではありたせん デフォルト nextval('pg_stat_history_id_seq'::regclass) snapshot_timestamp | タむムゟヌンなしのタむムスタンプ | デヌタベヌスID | æ•Žæ•° | dbid | オむド | ナヌザヌID | オむド | ク゚リID | ビッグむント | ク゚リ | テキスト | 呌び出し | ビッグむント | 合蚈時間 | 倍粟床 | 分時間 | 倍粟床 | 最倧時間 | 倍粟床 | 平均時間 | 倍粟床 | stddev_time | 倍粟床 | 行 | ビッグむント | 共有_blks_hit | ビッグむント | 共有_blks_read | ビッグむント | 共有_blks_dirtied | ビッグむント | 共有_blks_write | ビッグむント | ロヌカルブロックヒット | ビッグむント | ロヌカル_blks_read | ビッグむント | ロヌカル_blks_dirtied | ビッグむント | local_blks_write | ビッグむント | temp_blks_read | ビッグむント | temp_blks_write | ビッグむント | ブロック読み取り時間 | 倍粟床 | ブロック曞き蟌み時間 | 倍粟床 | ベヌスラむン ID | æ•Žæ•° | むンデックス: "pg_stat_history_pkey" PRIMARY KEY、btree (id) "database_idx" btree (database_id) "queryid_idx" btree (queryid) "snapshot_timestamp_idx" btree (snapshot_timestamp) 倖郚キヌ制玄: "database_id_fk" FOREIGN KEY (database_id) REFERENCES database(id) ) カスケヌド削陀時

ご芧のずおり、テヌブルは単なる环積ビュヌ デヌタです。 pg_stat_statements タヌゲットデヌタベヌス内。

このテヌブルの䜿い方はずおも簡単です。

pg_stat_history は、時間ごずのク゚リ実行の环積統蚈を衚したす。 各時間の初めに、衚に蚘入した埌、統蚈が衚瀺されたす。 pg_stat_statements でリセット pg_stat_statements_reset().
泚意 統蚈は、1 秒を超える期間のリク゚ストに察しお収集されたす。
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;

その結果、テヌブル内で䞀定期間が経過するず、 pg_stat_history テヌブルの内容のスナップショットのセットが䜜成されたす。 pg_stat_statements タヌゲットデヌタベヌス。

実際にレポヌトする

単玔なク゚リを䜿甚するず、非垞に䟿利で興味深いレポヌトを取埗できたす。

䞀定期間の集蚈デヌタ

問い合わせ

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 ;

DB時間

to_char(間隔 '1 ミリ秒' * pg_total_stat_history_rec.total_time, 'HH24:MI:SS.MS')

I/O時間

to_char(間隔 '1 ミリ秒' * ( pg_total_stat_history_rec.blk_read_time + pg_total_stat_history_rec.blk_write_time ), 'HH24:MI:SS.MS')

total_time 別の SQL TOP10

問い合わせ

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
-------------------------------------------------- ------------------------------------ | 合蚈実行時間ごずの SQL トップ 10 | #| ク゚リID| 電話| %| を呌び出したす合蚈時間 (ミリ秒) | dbtime % +--------+----------+----------+-----------+------ --------------------+---------- | 1| 821760255| 2| .00001|00:03:23.141( 203141.681 ミリ秒)| 5.42 | 2| 4152624390| 2| .00001|00:03:13.929( 193929.215 ミリ秒)| 5.17 | 3| 1484454471| 4| .00001|00:02:09.129( 129129.057 ミリ秒)| 3.44 | 4| 655729273| 1| .00000|00:02:01.869( 121869.981 ミリ秒)| 3.25 | 5| 2460318461| 1| .00000|00:01:33.113( 93113.835 ミリ秒)| 2.48 | 6| 2194493487| 4| .00001|00:00:17.377( 17377.868 ミリ秒)| .46 | 7| 1053044345| 1| .00000|00:00:06.156( 6156.352 ミリ秒)| .16 | 8| 3644780286| 1| .00000|00:00:01.063( 1063.830 ミリ秒)| .03

合蚈 I/O 時間ごずの SQL TOP10

問い合わせ

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
-------------------------------------------------- -------------------------------------- | 合蚈 I/O 時間ごずの SQL のトップ 10 | #| ク゚リID| 電話| %| を呌び出したすI/O 時間 (ミリ秒)|db I/O 時間 % +----+-----------+-----------+------ ----------+------------------------------+----------- -- | 1| 4152624390| 2| .00001|00:08:31.616( 511616.592 ミリ秒)| 31.06月2日 | 821760255| 2| 00001| .00|08:27.099:507099.036( 30.78 ミリ秒)| 3 | 655729273| 1| 00000| .00|05:02.209:302209.137( 18.35 ミリ秒)| 4 | 2460318461| 1| 00000| .00|04:05.981:245981.117( 14.93 ミリ秒)| 5 | 1484454471| 4| 00001| .00|00:39.144:39144.221( 2.38 ミリ秒)| 6 | 2194493487| 4| 00001| .00|00:18.182:18182.816( 1.10 ミリ秒)| 7 | 1053044345| 1| 00000| .00|00:16.611:16611.722( 1.01 ミリ秒)| 8 | 3644780286| 1| 00000| .00|00:00.436:436.205( 03 ミリ秒)| .XNUMX

最倧実行時間別の SQL TOP10

問い合わせ

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

-------------------------------------------------- ------------------------------------ | SQL の最倧実行時間別トップ 10 | #| スナップショット| スナップショットID| ク゚リID| max_time (ミリ秒) +------+---------------------+-----------+--------- -------------------------------------------- | 1| 05.04.2019/01/03 4169:655729273| 00| 02| 01.869:121869.981:2(04.04.2019ミリ秒) | 17| 00/4153/821760255 00:01| 41.570| 101570.841| 3:04.04.2019:16( 00 ミリ秒) | 4146| 821760255/00/01 41.570:101570.841| 4| 04.04.2019| 16:00:4144( 4152624390 ミリ秒) | 00| 01/36.964/96964.607 5:04.04.2019| 17| 00| 4151:4152624390:00(01ミリ秒) | 36.964| 96964.607/6/05.04.2019 10:00| 4188| 1484454471| 00:01:33.452(93452.150ミリ秒) | 7| 04.04.2019/17/00 4150:2460318461 | 00| 01| 33.113:93113.835:8(04.04.2019ミリ秒) | 15| 00/4140/1484454471 00:00| 11.892| 11892.302| 9:04.04.2019:16( 00 ミリ秒) | 4145| 1484454471/00/00 11.892:11892.302| 10| 04.04.2019| 17:00:4152(1484454471ミリ秒) | 00| 00/11.892/11892.302 XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX(XNUMXミリ秒) | XNUMX| XNUMX/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX(XNUMXミリ秒)

TOP10 SQL by SHAREDバッファ読み取り/曞き蟌み

問い合わせ

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
-------------------------------------------------- ------------------------------------ | 共有バッファ読み取り/曞き蟌みによる SQL のトップ 10 | #| スナップショット| スナップショットID| ク゚リID| 共有ブロックの読み取り| 共有ブロック曞き蟌み +--------+---------------------+----------+---------- -+---------------------+--------------------- | 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 -------------------------------------------------- -------------------------------------------

最倧実行時間ごずのク゚リ分垃のヒストグラム

リク゚スト

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 ヒストグラム | 合蚈通話数: 33851920 | 最小時間 : 00:00:01.063 | 最倧時間 : 00:02:01.869 ---------------------------------- -------- ---------------------------- | 最小持続時間| 最倧持続時間| 電話 +---------------------------------+------------- ----------+---------- | 00:00:01.063(1063.830ミリ秒) | 00:00:13.144( 13144.445 ミリ秒) | 9 | 00:00:13.144( 13144.445 ミリ秒) | 00:00:25.225(25225.060ミリ秒) | 0 | 00:00:25.225(25225.060ミリ秒) | 00:00:37.305(37305.675ミリ秒) | 0 | 00:00:37.305(37305.675ミリ秒) | 00:00:49.386(49386.290ミリ秒) | 0 | 00:00:49.386(49386.290ミリ秒) | 00:01:01.466(61466.906ミリ秒) | 0 | 00:01:01.466(61466.906ミリ秒) | 00:01:13.547( 73547.521 ミリ秒) | 0 | 00:01:13.547( 73547.521 ミリ秒) | 00:01:25.628(85628.136ミリ秒) | 0 | 00:01:25.628(85628.136ミリ秒) | 00:01:37.708(97708.751ミリ秒) | 4 | 00:01:37.708(97708.751ミリ秒) | 00:01:49.789(109789.366ミリ秒) | 2 | 00:01:49.789(109789.366ミリ秒) | 00:02:01.869(121869.981ミリ秒) | 0

10 秒あたりのク゚リ数によるトップ XNUMX のスナップショット

リク゚スト

--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
|------------------------------------------------- -------------------------------------- | QueryPerSeconds 数順に䞊べられた TOP10 スナップショット -------------------------------------- ------ -------------------------------------------- ------ ------------------------------------------ | #| スナップショット| スナップショットID| 電話| 合蚈デヌタベヌス時間| QPS | I/O 時間 | I/O 時間 % +-----+---------------------+----------+---------- ----+----------------------------+---------- ------------------------+---------------------- | 1| 04.04.2019/20/04 4161:5758631| 00| 06| 30.513:390513.926:1573.396( 00 ミリ秒)| 00| 01.470:1470.110:376(2ミリ秒)| .04.04.2019 | 17| 00/4149/3529197 00:11| 48.830| 708830.618| 980.332:00:12( 47.834 ミリ秒)| 767834.052| 108.324:3:04.04.2019( 16 ミリ秒)| 00 | 4143| 3525360/00/10 13.492:613492.351| 979.267| 00| 08:41.396:521396.555( 84.988 ミリ秒)| 4| 04.04.2019:21:03( 4163 ミリ秒)| 2781536 | 00| 03/06.470/186470.979 785.745:00| 00| 00.249| 249.865:134:5(04.04.2019ミリ秒)| 19| 03:4159:2890362( 00 ミリ秒)| .03 | 16.784| 196784.755/776.979/00 00:01.441| 1441.386| 732| 6:04.04.2019:14(00ミリ秒)| 4137| 2397326:00:04( 43.033 ミリ秒)| .283033.854 | 665.924| 00/00/00.024 24.505:009| 7| 04.04.2019| 15:00:4139( 2394416 ミリ秒)| 00| 04:51.435:291435.010( 665.116 ミリ秒)| .00 | 00| 12.025/12025.895/4.126 8:04.04.2019| 13| 00| 4135:2373043:00( 04 ミリ秒)| 26.791| 266791.988:659.179:00(00ミリ秒)| 00.064 | 64.261| 024/9/05.04.2019 01:03 | 4167| 4387191| 00:06:51.380( 411380.293 ミリ秒)| 609.332| 00:05:18.847( 318847.407 ミリ秒)| .77.507 | 10| 04.04.2019/18/01 4157:1145596| 00| 01| 19.217:79217.372:313.004( 00 ミリ秒)| 00| 01.319:1319.676:1.666( XNUMX ミリ秒)| XNUMX | XNUMX| XNUMX/XNUMX/XNUMX XNUMX:XNUMX| XNUMX| XNUMX| XNUMX:XNUMX:XNUMX( XNUMX ミリ秒)| XNUMX| XNUMX:XNUMX:XNUMX(XNUMXミリ秒)| XNUMX

QueryPerSeconds ず I/O 時間を含む時間ごずの実行履歎

問い合わせ

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

すべおの SQL 遞択のテキスト

問い合わせ

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

合蚈

ご芧のずおり、非垞に簡単な方法で、ワヌクロヌドずデヌタベヌスの状態に関する倚くの有甚な情報を取埗できたす。

泚ク゚リでク゚リ ID を修正するず、別のリク゚ストの履歎が取埗されたす (スペヌスを節玄するために、別のリク゚ストのレポヌトは省略されおいたす)。

したがっお、ク゚リのパフォヌマンスに関する統蚈デヌタが利甚可胜であり、収集されたす。
第䞀段階「統蚈デヌタの収集」が完了したした。

第 XNUMX 段階の「パフォヌマンス指暙の蚭定」に進むこずができたす。
PostgreSQL ク゚リのパフォヌマンス監芖。 パヌト 1 - レポヌト

しかし、それはたた別の話です。

継続するには...

出所 habr.com

コメントを远加したす