インスタンス内のクエリを診断および管理する方法について説明します。
概要
Hologres は PostgreSQL と互換性があります。hg_stat_activity (pg_stat_activity) ビューを使用して、インスタンス内のクエリのランタイム情報を監視し、分析と診断を行うことができます。このトピックでは、以下の操作について説明します。
hg_stat_activity (pg_stat_activity) ビュー:SQL のランタイム情報を表示して、SQL ステートメントをより適切に管理します。
HoloWeb でアクティブなクエリを管理する:HoloWeb コンソールを使用して、アクティブなクエリを表示および管理します。
ロックのトラブルシューティング:アクティブなクエリを使用して、SQL ステートメントがロックを保持しているか、ロックによってブロックされているかを特定します。
クエリの終了:コマンドを使用して、期待どおりに動作しないクエリを終了します。
アクティブなクエリのタイムアウトの変更:アクティブなクエリの実行タイムアウトを変更して、デッドロックを防ぎます。
アイドルクエリのタイムアウトの変更:アイドルクエリのタイムアウトを変更して、デッドロックを防ぎます。
低速クエリログの照会: 低速クエリログを使用して、低速または失敗したクエリを診断、分析、最適化します。
よくある質問:
ERROR: canceling statement due to statement timeoutエラーの原因と解決策について説明します。
Hologres では、単一のクエリに対するメモリまたは CPU 使用率の制限の設定はサポートされていません。クエリのリソースを制御するには、クエリキューを使用して、ワークロード全体のリソースを管理およびスケジュールすることを推奨します。
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 | query_id -----------------+-----------+----------+---------------+----------- 00:00:24.258388 | holotest | 123xxx | UPDATE xxx; | 1267xx 00:00:1.186394 | testdb | 156xx | select xxxx; | 1783xxこの結果は、
UPDATEステートメントが 24 秒間実行されているものの、完了していないことを示しています。
HoloWeb でのアクティブなクエリの管理
HoloWeb コンソールでは、アクティブなクエリを表示および管理できます。
HoloWeb コンソールにログインします。詳細については、「HoloWeb への接続とクエリの実行」をご参照ください。
トップナビゲーションバーで、Diagnostics and Optimization をクリックします。
左側のナビゲーションウィンドウで、Management for Information About Active Queries > Active Query Tasks を選択します。
Active Query Tasks ページで、Search をクリックすると、現在のインスタンスのアクティブなクエリを表示および管理できます。
結果リストには、以下の情報が含まれます。
パラメータ
説明
クエリ開始
クエリが開始された時刻。
実行時間
クエリの実行時間。
PID
クエリを処理するサービスのプロセス ID (PID)。
クエリ
実行された SQL ステートメント。
状態
接続の現在の状態。一般的な状態には、以下があります:
アクティブ:クエリが実行中です。
アイドル:接続がアイドル状態です。
トランザクション中のアイドル:トランザクション内で接続がアイドル状態です。
トランザクション中のアイドル (中止):失敗したトランザクション内で接続がアイドル状態です。
\N:状態が null です。これは通常、ユーザー接続ではなく、システムのバックグラウンドメンテナンスプロセスを示しており、無視できます。
ユーザー名
現在の接続のユーザー名。
アプリケーション
クエリを開始したアプリケーション。
クライアントアドレス
クライアントの IP アドレス。
長時間実行されているクエリを終了するには、そのクエリのActions列にあるCancelをクリックします。また、複数のクエリを選択してBatch Cancelをクリックすることもできます。
(オプション) クエリの詳細情報を表示するには、Actions列の詳細をクリックします。
詳細 ページでは、以下の操作を実行できます。
[Copy]:実行されたクエリの SQL ステートメントをコピーします。
[Format]:実行されたクエリの 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'
アクティブなクエリのタイムアウトの変更
アクティブなクエリの実行タイムアウトを変更できます。
構文
SET statement_timeout = <time>;パラメータの説明
time:タイムアウト期間を指定します。値の範囲は 0 ~ 2147483647 です。デフォルトの単位はミリ秒 (ms) です。別の単位を指定する場合は、値とその単位を単一引用符で囲みます。デフォルトのタイムアウトは 10 時間です。この設定はセッション固有です。説明タイムアウトを適用するには、
SET statement_timeout = <time>ステートメントを対象の SQL ステートメントと同じバッチで実行する必要があります。使用例
タイムアウトを 5,000 分に設定します。単位が指定されているため、値全体 '5000min' を単一引用符で囲む必要があります。
SET statement_timeout = '5000min'; SELECT * FROM tablename;タイムアウトを 5,000 ms に設定します。
SET statement_timeout = 5000; SELECT * FROM tablename;
アイドルクエリのタイムアウトの変更
idle_in_transaction_session_timeout パラメータは、トランザクションがアイドル状態になったときのタイムアウト動作を定義します。このパラメータが設定されていない場合、アイドルトランザクションはデフォルトでタイムアウトせず、トランザクションが解放されずにデッドロックが発生する可能性があります。アイドルクエリのタイムアウトを変更できます。
ユースケース
このタイムアウトを設定して、クエリがデッドロックを引き起こすのを防ぎます。たとえば、以下のコードはトランザクションを開始しますが、
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) です。別の単位を指定する場合は、値とその単位を単一引用符で囲みます。Hologres V0.10 以前では、デフォルト値は 0 で、アイドルトランザクションは自動的に終了されません。Hologres V1.1 以降では、デフォルト値は 10 分です。アイドル状態が 10 分を超えたトランザクションはロールバックされます。説明タイムアウトを非常に短い期間に設定しないでください。短いタイムアウトは、システムがまだ使用中のトランザクションを誤ってロールバックする原因となる可能性があります。
使用例
タイムアウトを 300,000 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 インスタンスでタイムアウトが設定されています。一般的なタイムアウト設定には、以下があります。
Data Service によって生成された API には、変更できない固定タイムアウト
10 sがあります。実行時間を短縮するために、SQL ステートメントを最適化することを推奨します。HoloWeb または DataWorks の Hologres SQL モジュールから実行されたクエリのタイムアウトは
1 hです。この値は変更できません。実行時間を短縮するために、SQL を最適化することを推奨します。Hologres インスタンスにタイムアウトが設定されています。以下の SQL ステートメントを実行して、インスタンスに設定されたタイムアウトを表示できます。エラーがインスタンスのタイムアウトによって引き起こされている場合は、ビジネス要件に基づいてタイムアウトをリセットできます。
SHOW statement_timeout;クライアントまたはアプリケーションにタイムアウトが設定されています。クライアントの設定を確認する必要があります。エラーがクライアントのタイムアウトによって引き起こされている場合は、ビジネス要件に基づいてタイムアウトをリセットできます。
原因 2:DML ステートメントの実行中にテーブルに対して
DROPまたはTRUNCATE操作が実行されたため、タイムアウトが発生しました。TRUNCATE操作は、テーブルを削除してから再作成することと同等です (drop+create)。DML ステートメントが実行されると、行ロックまたはテーブルロックを取得します。ロックの詳細については、「ロックとロックのトラブルシューティング」をご参照ください。同時に同じテーブルに対してDROPまたはTRUNCATE操作が実行されると、DML ステートメントが保持しているロックと競合します。その後、システムは DML ステートメントをキャンセルし、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';