このトピックでは、インスタンス内のクエリを診断および管理する方法について説明します。
概要
Hologres は PostgreSQL と互換性があります。インスタンス内のクエリの実行時情報を表示するには、HG_STAT_ACTIVITY (PG_STAT_ACTIVITY) ビューを使用します。これにより、実行中の SQL 文を分析・診断できます。主な操作は以下のとおりです。
-
HG_STAT_ACTIVITY (PG_STAT_ACTIVITY) ビュー:SQL の実行時情報を表示し、SQL 文を効率的に管理します。
-
HoloWeb コンソールでのアクティブクエリの管理:HoloWeb コンソールでアクティブクエリを表示および管理します。
-
ロックのトラブルシューティング:アクティブクエリを使用して、現在の 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 コンソールでのアクティブクエリの管理
HoloWeb コンソールでアクティブクエリを表示および管理できます。
-
HoloWeb コンソールにログインします。詳細については、「HoloWeb への接続とクエリの実行」をご参照ください。
-
上部ナビゲーションバーで、Diagnostics and Optimization をクリックします。
-
左側のナビゲーションウィンドウで、Management for Information About Active Queries > Active Query Tasks の順に選択します。
-
Active Query Tasks ページで、Search をクリックして、現在のインスタンスのアクティブクエリを表示および管理します。
クエリ結果リストには以下の情報が含まれます。
パラメーター
説明
Query Start
クエリの開始時刻。
Runtime
クエリの実行時間。
PID
クエリサービスプロセスの ID。
Query
実行されている SQL 文。
State
現在の接続のステータス。一般的なステータスは以下のとおりです。
-
active:接続がアクティブです。
-
idle:アイドル状態です。
-
idle in transaction:長時間トランザクション内で接続がアイドル状態です。
-
idle in transaction (Aborted):失敗したトランザクション内で接続がアイドル状態です。
-
\N:ステータスが空です。これはユーザ接続ではないプロセスを示しており、通常はシステムのバックグラウンドメンテナンスプロセスであるため、無視できます。
User Name
現在の接続のユーザー名。
Application
クエリアプリケーションの種類。
Client Address
クエリを開始したクライアントの 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'
アクティブクエリのタイムアウト期間の変更
Hologres では、アクティブクエリのタイムアウト期間を以下のように変更できます。
-
構文例
SET statement_timeout = <time>; -
パラメーターの説明
time:タイムアウト期間。値の範囲は 0 ~ 2147483647 です。デフォルトの単位はミリ秒 (ms) です。時間値に単位を指定する場合は、必ずシングルクォーテーションで囲む必要があります。囲まないとエラーが発生します。デフォルトのタイムアウト期間は 8 時間です。この設定はセッションレベルで有効です。
説明`SET statement_timeout = <time>` 文は、タイムアウト期間を変更したい SQL 文と同時に実行する必要があります。
-
例
-
タイムアウト期間を 5000 分に設定します。値 `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) です。時間値に単位を指定する場合は、必ずシングルクォーテーションで囲む必要があります。囲まないとエラーが発生します。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 のタイムアウト期間は
10 sであり、変更できません。SQL 文を最適化して実行時間を短縮してください。 -
HoloWeb コンソールまたは DataWorks の Hologres SQL モジュールでクエリが実行されています。タイムアウト期間は
1 hであり、変更できません。SQL 文を最適化して実行時間を短縮してください。 -
Hologres インスタンスにタイムアウト期間が設定されています。以下の SQL 文を実行して、インスタンスに設定されたタイムアウト期間を確認できます。インスタンスタイムアウトが原因の場合は、必要に応じて適切な値に再設定してください。
SHOW statement_timeout; -
クライアントまたはアプリケーションにタイムアウト期間が設定されています。クライアントの設定を確認してください。クライアントタイムアウトが原因の場合は、必要に応じて適切な値に再設定してください。
-
-
原因 2:Data Manipulation Language (DML) SQL 文がテーブル上で実行されている間に、同じテーブルに対して `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';
-