このトピックでは、Hologresインスタンスでクエリに関連する問題を診断し、クエリを管理する方法について説明します。
概要
Hologres は PostgreSQL と互換性があります。HG_STAT_ACTIVITY (PG_STAT_ACTIVITY) ビューを使用して、Hologres インスタンス上のクエリの 実行 情報を表示できます。これは、クエリ実行情報を分析し、関連する問題を診断するのに役立ちます。クエリ管理機能には、次の操作が含まれます。
HG_STAT_ACTIVITY (PG_STAT_ACTIVITY) ビューを使用する: SQL 文のランタイム情報を表示して、SQL 文をより適切に管理します。
HoloWebを使用して、視覚化された方法でアクティブなクエリを表示および管理する: HoloWebを使用して、視覚化された方法でアクティブなクエリを表示および管理します。
ロックの問題のトラブルシューティング: アクティブなクエリのSQLステートメントがロックを取得しているか、ロックが解放されるのを待機しているかを確認します。
クエリをキャンセルする: ステートメントを実行することにより、期待どおりでないクエリをキャンセルします。
アクティブなクエリのタイムアウト期間を変更する: デッドロックを防ぐために、アクティブなクエリのタイムアウト期間を変更します。
アイドル状態のクエリのタイムアウト期間を変更する: デッドロックを防ぐために、アイドル状態のクエリのタイムアウト期間を変更します。
低速クエリログをクエリする: 低速クエリログをクエリして、低速クエリまたは失敗したクエリを診断、分析、および最適化します。
FAQ: エラーメッセージ
ERROR: canceling statement due to statement timeout
が報告された場合に問題を解決します。
アクティブなクエリの SQL ステートメントを使用した表示
このセクションでは、SQL ステートメントを使用してアクティブなクエリを表示する方法について説明します。
現在アクティブなクエリ、および現在アクティブなクエリの実行ステージとリソース消費量を表示します。
説明Hologres インスタンスのスーパーユーザーは、Hologres インスタンスのすべてのユーザーによって送信された 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 に接続してクエリを実行する」をご参照ください。
上部のナビゲーションバーで、[診断と最適化] をクリックします。
左側のナビゲーションペインで、[アクティブなクエリ情報の管理] > [アクティブなクエリタスク] を選択します。
[アクティブなクエリタスク] ページで、[クエリ] をクリックして、現在のインスタンスのアクティブなクエリを表示および管理します。
次の表は、クエリ結果のパラメーターについて説明しています。
パラメーター
説明
クエリの開始
クエリの実行が開始された時刻。
実行時間
クエリが実行されている期間。
PID
クエリのプロセス ID(PID)。
クエリ
データのクエリを実行するために実行される 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 では、SQL ステートメントを実行することで、アクティブなクエリのタイムアウト期間を変更できます。
構文
SET statement_timeout = <time>;
パラメーター
time: アクティブなクエリのタイムアウト期間。有効な値: 0 ~ 2147483647。デフォルト単位: ミリ秒。指定した時間値に単位を追加する場合は、値と単位を単一引用符 (') で囲みます。そうしないと、エラーメッセージが返されます。現在のデフォルトのタイムアウト期間は 8 時間です。タイムアウト期間の設定は、現在のセッションのクエリに対してのみ有効です。
説明SET statement_timeout = <time> ステートメントは、タイムアウト期間を変更する SQL ステートメントと共に実行された場合にのみ有効になります。
例
タイムアウト期間を 5,000 分に設定します。指定した時間値に単位を追加する場合は、値と単位を単一引用符 (') で囲みます。
SET statement_timeout = '5000min' ; SELECT * FROM tablename;
タイムアウト期間を 5,000 ms に設定します。
SET statement_timeout = 5000 ; SELECT * FROM tablename;
アイドル状態のクエリのタイムアウト期間を変更する
idle_in_transaction_session_timeout パラメーターは、トランザクションがアイドル状態になった後のタイムアウト動作を指定します。このパラメーターを設定しない場合、タイムアウトしたトランザクションはロールバックされません。その結果、クエリ中にデッドロックが発生する可能性があります。Hologres では、SQL ステートメントを実行することで、アイドル状態のクエリのタイムアウト期間を変更できます。
シナリオ
クエリ中のデッドロックを防ぐには、アイドル状態のクエリのタイムアウト期間を指定する必要があります。たとえば、次のコードはトランザクションを開始しますが、
COMMIT
文を使用してコミットしません。これにより、トランザクションリークが発生し、最終的にデータベースレベルのデッドロックが発生し、データベースの通常の使用に影響します。BEGIN; SELECT * FROM t;
idle_in_transaction_session_timeout パラメーターを設定してタイムアウト期間を指定することで、この問題を解決できます。接続が idle_in_transaction_session_timeout パラメーターで指定されたタイムアウト期間よりも長くアイドル状態になった後、トランザクションがコミットまたはロールバックされていない場合、Hologres はトランザクションを自動的にロールバックし、接続を閉じます。
構文
-- セッション内のアイドル状態のトランザクションのタイムアウト期間を変更します。 SET idle_in_transaction_session_timeout=<time>; -- データベース内のアイドル状態のトランザクションのタイムアウト期間を変更します。 ALTER database db_name SET idle_in_transaction_session_timeout=<time>;
パラメーター
time: アクティブなクエリのタイムアウト期間。有効な値: 0 ~ 2147483647。デフォルトの単位: ミリ秒。指定した時間値に単位を追加する場合は、値と単位を単一引用符 (' ') で囲みます。そうしないと、エラーが返されます。Hologres V0.10 以前では、このパラメーターのデフォルト値は 0 です。これは、アイドル状態のトランザクションが自動的にロールバックされないことを意味します。Hologres V1.1 では、このパラメーターのデフォルト値は 600000 に変更され、これは 10 分を示します。トランザクションが 10 分以上アイドル状態の場合、トランザクションはロールバックされます。
説明タイムアウト期間が必要以上に短い場合、使用中のトランザクションが誤ってロールバックされる可能性があります。アイドル状態のトランザクションに適切なタイムアウト期間を設定することをお勧めします。
例
タイムアウト期間を 300,000 ミリ秒に設定します。
-- セッション内のアイドル状態のトランザクションのタイムアウト期間を変更します。 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 ノードを使用してクエリを実行する場合、クエリの実行のタイムアウト期間は
1 時間
であり、変更できません。実行時間を短縮するために SQL 文を最適化することをお勧めします。Hologresインスタンスにタイムアウト期間が設定されている場合は、次のSQLステートメントを実行してタイムアウト期間を照会できます。タイムアウト期間の設定が不適切なためにエラーが発生した場合は、タイムアウト期間を変更します。
SHOW statement_timeout;
クライアントまたはアプリケーションにタイムアウト期間が設定されている場合は、クライアントまたはアプリケーションの設定を確認する必要があります。クライアントによって指定されたタイムアウト期間が原因でエラーが発生した場合は、ビジネス要件に基づいて適切なタイムアウト期間を指定できます。
原因 2: DMLステートメントの実行時に、DROPまたはTRUNCATEステートメントがテーブルで実行されます。
TRUNCATE の実行は、
DROP と CREATE
の両方を実行することと同じです。 TRUNCATE 文を実行すると、テーブルが削除され、再度作成されます。 DML 文が実行されると、行ロックまたはテーブルロックが取得されます。ロックの詳細については、「ロックとロックのトラブルシューティング」をご参照ください。同時に DROP または TRUNCATE 文がテーブルで実行されると、DROP または TRUNCATE 文はロックを取得します。この場合、システムは DML 文をキャンセルします。その結果、statement timeout
エラーメッセージが返されます。解決策: 低速クエリログを使用して、DML 文が実行されているときに
DROP
またはTRUNCATE
文がテーブルで実行されているかどうかを確認します。次のサンプルコードは例を示しています。 DML 文が実行されているときに DROP または TRUNCATE 文を実行しないことをお勧めします。-- Query records of the DROP and TRUNCATE statements that are executed on a table in the previous day. 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';