このトピックでは、インスタンス内のクエリを診断および管理する方法について説明します。
概要
Hologres は PostgreSQL と互換性があります。HG_STAT_ACTIVITY (PG_STAT_ACTIVITY) ビューを使用してインスタンス内のクエリ実行に関する情報を表示し、実行中の SQL 文を分析および診断できます。クエリ管理には、次の操作が含まれます。
HG_STAT_ACTIVITY (PG_STAT_ACTIVITY) ビュー:SQL 文のランタイム情報を表示して、管理を改善します。
HoloWeb でのアクティブなクエリの GUI 管理:HoloWeb を使用して、GUI でアクティブなクエリを表示および管理します。
ロックのトラブルシューティング:アクティブなクエリを使用して、SQL 文がロックを取得したか、ロックによってブロックされているかを確認します。
クエリのキャンセル:コマンド文を使用して、不要なクエリをキャンセルします。
アクティブなクエリのタイムアウト期間の変更:アクティブなクエリのタイムアウト期間を変更して、デッドロックを防ぎます。
アイドル状態のクエリのタイムアウト期間の変更:アイドル状態のクエリのタイムアウト期間を変更して、デッドロックを防ぎます。
スロークエリログのクエリ:スロークエリログをクエリして、遅いクエリや失敗したクエリを診断、分析、最適化します。
よくある質問:
ERROR: canceling statement due to statement timeoutエラーの原因とソリューションを見つけます。
SQL 文を使用したアクティブなクエリの表示
SQL 文を使用してアクティブなクエリを表示する場合は、次の SQL 文を使用できます。
現在のアクティブなクエリと、それに対応する実行ステージおよびリソース消費量を表示します。
説明スーパーユーザーはすべてのユーザーの SQL 実行情報を表示できます。スーパーユーザー以外のユーザーは、自身の SQL 実行情報のみ表示できます。
-- Hologres V2.0 以降の構文 SELECT query,state,query_id,transaction_id,running_info, extend_info FROM hg_stat_activity WHERE state = 'active' AND backend_type = 'client backend' AND application_name != 'hologres' -- Hologres V1.3 以前の構文 SELECT query,state,pid FROM pg_stat_activity WHERE state = 'active' AND backend_type = 'client backend' AND application_name != 'hologres'出力例は次のとおりです。
------------------------------------------------------------------------------- query | insert into test_hg_stat_activity select i, (i % 7) :: text, (i % 1007) from generate_series(1, 10000000)i; state | active query_id | 100713xxxx transaction_id | 100713xxxx running_info | {"current_stage" : {"stage_duration_ms" :5994, "stage_name" :"EXECUTE" }, "engine_type" :"{HQE,PQE}", "fe_id" :1, "warehouse_id" :0 } extend_info | {"affected_rows" :9510912, "scanned_rows" :9527296 }実行中のクエリを CPU 消費量で並べ替えます。
-- Hologres V2.0 以降の構文 SELECT query,((extend_info::json)->'total_cpu_max_time_ms')::text::bigint AS cpu_cost,state,query_id,transaction_id FROM hg_stat_activity WHERE state = 'active' ORDER BY 2 DESC;出力例は次のとおりです。
--------------------------------------------------------------------------------- query | select xxxxx cpu_cost | 523461 state | active query_id | 10053xxxx transaction_id | 10053xxxx --------------------------------------------------------------------------------- query | insert xxxx cpu_cost | 4817 state | active query_id | 1008305xxx transaction_id | 1008305xxx実行中のクエリをメモリ消費量で並べ替えます。
-- Hologres V2.0 以降の構文 SELECT query,((extend_info::json)->'total_mem_max_bytes')::text::bigint AS mem_max_cost,state,query_id,transaction_id FROM hg_stat_activity WHERE state = 'active' ORDER BY 2 DESC;出力例は次のとおりです。
--------------------------------------------------------------------------------- query | update xxxx; mem_max_cost | 5727634542 state | active query_id | 10053302784827629 transaction_id | 10053302784827629 --------------------------------------------------------------------------------- query | select xxxx; mem_max_cost | 19535640 state | active query_id | 10083259096119559 transaction_id | 10083259096119559現在のインスタンスで実行されている長時間実行クエリを表示します。
-- Hologres V2.0 以降の構文 SELECT current_timestamp - query_start AS runtime, datname::text, usename, query, query_id FROM hg_stat_activity WHERE state != 'idle' AND backend_type = 'client backend' AND application_name != 'hologres' ORDER BY 1 DESC; -- Hologres V1.3 以前の構文 SELECT current_timestamp - query_start AS runtime, datname::text, usename, query, pid FROM pg_stat_activity WHERE state != 'idle' AND backend_type = 'client backend' AND application_name != 'hologres' ORDER BY 1 DESC;出力例は次のとおりです。
runtime | datname | usename | query_id | current_query -----------------+----------------+----------+------------------------------------ 00:00:24.258388 | holotest | 123xxx | 1267xx | UPDATE xxx; 00:00:1.186394 | testdb | 156xx | 1783xx | select xxxx;この結果は、UPDATE クエリに時間がかかっていることを示しています。24 秒間実行されていますが、まだ完了していません。
HoloWeb でのアクティブなクエリの GUI 管理
HoloWeb を使用して、GUI でアクティブなクエリを表示および管理できます。
HoloWeb コンソールにログインします。詳細については、「HoloWeb に接続してクエリを実行する」をご参照ください。
上部のナビゲーションバーで、[診断と最適化] をクリックします。
左側のナビゲーションウィンドウで、[アクティブ情報管理] > [アクティブなクエリ] に移動します。
[アクティブなクエリ] ページで、[クエリ] をクリックして、現在のインスタンスのアクティブなクエリを表示および管理します。
クエリ結果リストには、次の情報が含まれています。
パラメーター
説明
クエリの開始
クエリが開始された時刻。
実行時間
クエリが実行されている時間。
PID
サービスプロセスの ID をクエリできます。
クエリ
クエリで実行される SQL 文。
状態
現在の接続の状態。一般的な状態は次のとおりです。
active:接続はアクティブです。
idle:コンポーネントが使用されていません。
idle in transaction:接続は長時間実行トランザクションでアイドル状態です。
idle in transaction (Aborted):接続は失敗したトランザクションでアイドル状態です。
\N:状態が空です。これは、ユーザー接続ではないプロセスを示します。通常はシステムのバックグラウンドメンテナンスプロセスであり、無視できます。
ユーザー名
現在の接続のユーザー名。
アプリケーション
クエリのアプリケーションの種類。
クライアントアドレス
クライアントの IP アドレスをクエリできます。
クエリの実行時間が長い場合は、[操作] 列の [キャンセル] をクリックして停止できます。複数のクエリを選択して、[一括キャンセル] 操作を実行することもできます。
(任意) 対象クエリの詳細を表示するには、[操作] 列の [詳細] をクリックします。
[詳細] ページで、次の手順を実行します。
[コピー]:現在のクエリの SQL 文をコピーします。
[フォーマット]:現在のクエリの SQL 文をフォーマットします。
ロックのトラブルシューティング
アクティブなクエリを使用して、SQL 文がロックを取得したか、ロックによってブロックされているかを確認できます。詳細については、「ロックとロックのトラブルシューティング」をご参照ください。
クエリの停止
不要なクエリをキャンセルするには、次のコマンド文を使用できます。
単一のクエリをキャンセルする:
SELECT pg_cancel_backend(<pid>);クエリを一括でキャンセルする:
SELECT pg_cancel_backend(pid) ,query ,datname ,usename ,application_name ,client_addr ,client_port ,backend_start ,state FROM pg_stat_activity WHERE length(query) > 0 AND pid != pg_backend_pid() AND backend_type = 'client backend' AND application_name != 'hologres'
アクティブなクエリのタイムアウト期間の変更
Hologres では、次の方法でアクティブなクエリのタイムアウト期間を変更できます。
構文例
SET statement_timeout = <time>;パラメーターの説明
time:タイムアウト期間。値は 0 から 2147483647 までの整数である必要があります。デフォルトの単位はミリ秒 (ms) です。time の値に単位を指定する場合は、値と単位を単一引用符 (') で囲む必要があります。そうしないと、エラーが報告されます。デフォルトのタイムアウト期間は 8 時間です。この設定はセッションレベルで有効になります。
説明新しいタイムアウト期間を有効にするには、`SET statement_timeout = ` 文を SQL 文と一緒に実行する必要があります。
例
タイムアウト期間を 5000 分に設定します。time の値には単位が含まれているため、'5000min' は単一引用符で囲む必要があります。
SET statement_timeout = '5000min' ; SELECT * FROM tablename;タイムアウト期間を 5000 ms に設定します。
SET statement_timeout = 5000 ; SELECT * FROM tablename;
アイドル状態のクエリのタイムアウト期間の変更
idle_in_transaction_session_timeout パラメーターは、アイドル状態のトランザクションのタイムアウト期間を指定します。このパラメーターが設定されていない場合、デフォルトではアイドル状態のトランザクションは解放されません。これにより、解放されていないトランザクションが蓄積され、デッドロックにつながる可能性があります。Hologres では、次の方法でアイドル状態のクエリのタイムアウト期間を変更できます。
シナリオ
クエリの実行によってデッドロックが発生する場合は、タイムアウト期間を設定する必要があります。たとえば、次のコードでは、
commitが実行されないため、トランザクションは開始されますがコミットされません。これにより、トランザクションリークが発生し、データベースレベルのデッドロックにつながり、サービスの正常な運用に影響を与える可能性があります。BEGIN; SELECT * FROM t;デッドロックを解決するには、idle_in_transaction_session_timeout パラメーターを設定します。アイドル状態の接続上のトランザクションが idle_in_transaction_session_timeout で指定された期間内にコミットまたはロールバックされない場合、システムは自動的にトランザクションをロールバックし、接続を閉じます。
構文例
-- セッションのアイドル状態のトランザクションのタイムアウト期間を変更します。 SET idle_in_transaction_session_timeout=<time>; -- データベースレベルでアイドル状態のトランザクションのタイムアウト期間を変更します。 ALTER database db_name SET idle_in_transaction_session_timeout=<time>;パラメーターの説明
time:タイムアウト期間。値は 0 から 2147483647 までの整数である必要があります。デフォルトの単位はミリ秒 (ms) です。time の値に単位を指定する場合は、値と単位を単一引用符 (') で囲む必要があります。そうしないと、エラーが報告されます。Hologres V0.10 以前では、デフォルト値は 0 で、アイドル状態のトランザクションは自動的にクリアされないことを意味します。Hologres V1.1 以降では、デフォルト値は 10 分です。10 分以上アイドル状態のトランザクションはロールバックされます。
説明タイムアウト期間を短すぎる値に設定しないでください。タイムアウト期間が短いと、使用中のトランザクションが誤ってロールバックされる可能性があります。
例
タイムアウト期間を 300000 ms に設定します。
-- セッションのアイドル状態のトランザクションのタイムアウト期間を変更します。 SET idle_in_transaction_session_timeout=300000; -- データベースレベルでアイドル状態のトランザクションのタイムアウト期間を変更します。 ALTER database db_name SET idle_in_transaction_session_timeout=300000;
低速クエリログのクエリ
Hologres V0.10 以降では、低速クエリログをクエリできます。詳細については、「低速クエリログのクエリと分析」をご参照ください。
よくある質問
問題
SQL 文を実行すると、次のエラーが報告されます:
ERROR: canceling statement due to statement timeout。原因とソリューション
原因 1:クライアントまたは Hologres インスタンスにタイムアウト期間が設定されています。一般的なタイムアウトシナリオは次のとおりです。
DataService Studio を使用して API を生成します。DataService Studio のタイムアウト期間は
10sであり、変更できません。SQL 文を最適化して実行時間を短縮する必要があります。HoloWeb または DataWorks の Hologres SQL モジュールを使用してクエリを実行します。タイムアウト期間は
1hであり、変更できません。SQL 文を最適化して実行時間を短縮する必要があります。Hologres インスタンスにタイムアウト期間が設定されています。次の SQL 文を実行して、インスタンスのタイムアウト期間を表示できます。インスタンスのタイムアウト期間がエラーの原因である場合は、必要に応じてタイムアウト期間をリセットできます。
SHOW statement_timeout;クライアントまたはアプリケーションにタイムアウト期間が設定されています。クライアントの設定を確認する必要があります。クライアントのタイムアウト期間がエラーの原因である場合は、必要に応じてタイムアウト期間をリセットできます。
原因 2:データ操作言語 (DML) SQL 文の実行中にテーブルに対して DROP または TRUNCATE 操作が実行され、タイムアウトが発生します。
TRUNCATE 操作は
drop+createと同等です。最初にテーブルをドロップし、次に再作成します。DML SQL 文が実行されると、行ロックまたはテーブルロックを取得します。ロックの詳細については、「ロックとロックのトラブルシューティング」をご参照ください。同時に同じテーブルに対して DROP または TRUNCATE 操作を実行すると、DROP または TRUNCATE 操作は DML 文が保持しているロックを競合します。その後、システムは DML SQL 文をキャンセルし、statement timeoutエラーが発生します。ソリューション:スロークエリログをチェックして、
dropまたはtruncate操作が同時にテーブルに対して実行されたかどうかを判断します。これらの操作を同時に実行することは避けるべきです。次の例は、ログのチェック方法を示しています。-- 例:過去 1 日間にテーブルに対して実行された drop/truncate 操作のレコードをクエリします。 SELECT * FROM hologres.hg_query_log WHERE command_tag IN ('DROP TABLE','TRUNCATE TABLE') AND query LIKE '%xxx%' AND query_start >= now() - interval '1 day';