ApsaraDB RDS for PostgreSQL の pg_concurrency_control プラグインを使用すると、SELECT クエリ、DML ステートメント、スロークエリ、トランザクションブロックなど、ステートメントの種別ごとに同時実行数を制限できます。設定した上限に達したステートメントは、即座に実行されるのではなくキュー内で待機するため、高同時実行ワークロード下でのリソース枯渇を防止できます。
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
PostgreSQL 10 または 11 を実行している ApsaraDB RDS for PostgreSQL インスタンス
インスタンスのバージョンを確認するには、データベースで SELECT version(); を実行します。
プラグインのインストール
以下のコマンドを実行して拡張機能を作成します。
CREATE EXTENSION pg_concurrency_control;同時実行数の制限設定
各同時実行パラメーターのデフォルト値は 0 であり、この値は対象のステートメント種別について同時実行制御を無効化します。制限を有効にするには、パラメーターを正の整数に設定します。
たとえば、SELECT ステートメントの同時実行制御を有効化するには、pg_concurrency_control.query_concurrency を 10 に設定します。他のステートメント種別についても同様の方法で設定します。
ステートメントをスロークエリとして認識させ、bigquery_concurrency 制限の対象とするには、/*+bigsql*/ ヒントワードを先頭に付加します。
/*+bigsql*/ SELECT * FROM test;パラメーター リファレンス
同時実行制御パラメーター
| パラメーター | デフォルト値 | 有効な値 | 説明 |
|---|---|---|---|
pg_concurrency_control.query_concurrency | 0 | 0–1024 | SELECT ステートメントの最大同時実行ジョブ数です。0 を指定すると制御が無効になります。 |
pg_concurrency_control.bigquery_concurrency | 0 | 0–1024 | スロークエリの最大同時実行ジョブ数です。0 を指定すると制御が無効になります。/*+bigsql*/ ヒントワードを使用してステートメントをスロークエリとしてマークします。 |
pg_concurrency_control.transaction_concurrency | 0 | 0–1024 | トランザクションブロックの最大同時実行ジョブ数です。0 を指定すると制御が無効になります。 |
pg_concurrency_control.autocommit_concurrency | 0 | 0–1024 | DML ステートメントの最大同時実行ジョブ数です。0 を指定すると制御が無効になります。 |
タイムアウト パラメーター
| パラメーター | デフォルト値 | 有効な値 | 説明 |
|---|---|---|---|
pg_concurrency_control.control_timeout | 1s | 30ms–3s | SELECT ステートメント、DML ステートメント、またはトランザクションブロックがキュー内で待機できる最大時間です。この時間を超えるとタイムアウト操作が実行されます。 |
pg_concurrency_control.bigsql_control_timeout | 1s | 30ms–3s | スロークエリがキュー内で待機できる最大時間です。この時間を超えるとタイムアウト操作が実行されます。 |
pg_concurrency_control.timeout_action | TCC_break | TCC_break、TCC_rollback、TCC_wait | SELECT ステートメント、DML ステートメント、またはトランザクションブロックがキュー内で待機中にタイムアウトした場合の操作です。詳細については、「タイムアウト操作の値」をご参照ください。 |
pg_concurrency_control.bigsql_timeout_action | TCC_wait | TCC_break、TCC_rollback、TCC_wait | スロークエリがキュー内で待機中にタイムアウトした場合の操作です。詳細については、「タイムアウト操作の値」をご参照ください。 |
タイムアウト操作の値
| 値 | 動作 |
|---|---|
TCC_break | 待機中のステートメントをスキップし、次のステートメントを実行します。 |
TCC_rollback | エラーを報告し、トランザクションをロールバックします。 |
TCC_wait | タイムアウト後にタイムスタンプをリセットし、引き続き待機します。 |
キュー状態の確認
pg_concurrency_control_status() 関数を使用して、現在のステートメントキューを確認します。この関数は、各キューで現在待機中のステートメント数を返します。
SELECT * FROM pg_concurrency_control_status();キューにステートメントが登録されていない場合の出力例:
autocommit_count | bigquery_count | query_count | transaction_count
------------------+----------------+-------------+-------------------
0 | 0 | 0 | 0
(1 行)非ゼロのカウント値は、制限が有効であり、ステートメントがキューに登録されていることを示します。キューに登録されたステートメントが完了またはタイムアウトすると、カウント値は自動的に減少します。
例:スロークエリ制限が有効であることを確認する
以下の例では、bigquery_concurrency 制限下でスロークエリが実行されている際のキュー状態を示します。
クエリを実行する前にキューを確認します。
SELECT * FROM pg_concurrency_control_status();autocommit_count | bigquery_count | query_count | transaction_count ------------------+----------------+-------------+------------------- 0 | 0 | 0 | 0 (1 行)SELECT ステートメントの同時実行制御を有効化するため、
pg_concurrency_control.query_concurrencyを10に設定します。/*+bigsql*/ヒントワードを使用してスロークエリを実行します。/*+ bigsql */ SELECT pg_sleep(10);スロークエリの実行中に、別のセッションからキューを確認します。
SELECT * FROM pg_concurrency_control_status();autocommit_count | bigquery_count | query_count | transaction_count ------------------+----------------+-------------+------------------- 0 | 1 | 0 | 0 (1 行)bigquery_countが1であることは、スロークエリがキュー内でトラッキングされていることを確認できます。クエリが完了すると、カウント値は自動的にクリアされます。