すべてのプロダクト
Search
ドキュメントセンター

PolarDB:SQL スロットリング

最終更新日:Jun 25, 2025

PolarDB for PostgreSQL (Oracle 互換) は、SQL スロットリング機能を提供します。 この機能を使用すると、エンドポイントに基づいてスロットリングルールを設定し、異常トラフィックおよび SQL 文がビジネスオペレーションに及ぼす影響を軽減できます。 このトピックでは、SQL スロットリング機能の使用方法について説明します。

概要

SQL スロットリング機能を使用すると、エンドポイントに基づいてスロットリングルールを確立できます。 SQL テンプレートを使用して現在のエンドポイントで実行されている SQL 文を識別し、その最大同時操作数または QPS を制限します。 この機能は、以下のシナリオで役立ちます。

  • PolarDB クラスタでデータベースのワークロードが高くなり、通常のビジネスオペレーションが中断される原因となる低速の SQL クエリが発生する。

  • 特定の種類のリスクの高い SQL に割り当てられるリソースを制限したり、その実行を完全にブロックしたりする。

手順

説明

SQL スロットリング機能を有効にするには、お問い合わせください

  1. [PolarDB コンソール] にログインします。 左側のナビゲーションウィンドウで、[クラスタ] をクリックします。 左上隅で、クラスタのリージョンを選択します。 クラスタリストで、クラスタを見つけてその ID をクリックし、[基本情報] ページに移動します。

  2. 左側のナビゲーションウィンドウで、[設定と管理] > [セキュリティ] をクリックします。

  3. [SQL スロットリング] タブで、[追加] をクリックして、新しい SQL スロットリングルールを作成します。

    image

  4. [新しい SQL スロットリングルール] ポップアップウィンドウで、以下の構成項目を設定し、[OK] をクリックします。

    セクション

    パラメーター

    説明

    基本情報

    ルール名

    スロットリングルールの名前。 以下の要件を満たしている必要があります。

    • 最大 30 文字。

    • 大文字と小文字、数字を含めることができます。

    ルールの説明

    オプション。 後続の管理のためのスロットリングルールに関する関連情報。 最大 64 文字まで入力できます。

    エンドポイント ID

    スロットリングルールが適用されるエンドポイント。

    説明
    • アクティブリクエスト(読み取り/書き込みまたは読み取り専用の両方)に基づく負荷分散を使用するクラスタエンドポイントとカスタムエンドポイントのみが、スロットリングルールをサポートします。 接続に基づく負荷分散を使用するプライマリエンドポイントと読み取り専用エンドポイントは、SQL スロットリングをサポートしていません。

    • 異なるエンドポイントで構成されたスロットリングルールは、互いに影響しません。 同じエンドポイントで構成されたスロットリングルールは、そのエンドポイントを使用するビジネス接続にのみ適用されます。

    ルール構成

    ルールタイプ

    スロットリングルールモード。 有効な値: [アクティブな同時実行文のスロットリング] および [接続ごとの QPS のスロットリング]

    説明

    [接続ごとの QPS のスロットリング] モードは、単一の接続に対する 1 秒あたりのリクエスト数を制限します。 ビジネス側で接続プールが構成されている場合、または持続的接続を使用している場合に使用できます。 短期接続のシナリオでは、[アクティブな同時実行文のスロットリング] モードをお勧めします。

    現在のモード

    SQL テンプレートのマッチングモード。 有効な値: [テンプレートマッチ] および [全文一致]。 2 つのマッチングモードの違いについては、「テンプレートマッチングと全文一致」をご参照ください。

    データベースアカウント名

    スロットリングルールが適用されるアカウント。 最大 10 個のアカウントを構成できます。 複数のアカウント名はコンマで区切ります。 空の場合、デフォルトですべてのアカウントに適用されます。

    データベース名

    スロットリングルールが適用されるデータベース。 最大 10 個のデータベースを構成できます。 複数のデータベース名はコンマで区切ります。 空の場合、デフォルトですべてのデータベースに適用されます。

    SQL テンプレート

    SQL テンプレート。 詳細については、「SQL テンプレートとマッチングモード」をご参照ください。

    最大待機キューの長さ

    待機キューの最大数。 有効な値: 0 ~ 1024。 同時実行文または QPS のしきい値に達すると、リクエストは再試行のためにキューに入れられます。 待機キューの最大数を超えると、新しいリクエストによってエラーが発生します。 待機キューの最大数を適切に構成することで、多くの SQL 文がスロットリングされたときに待機キューが無制限に増加することを防ぎ、PolarProxy のメモリ不足が発生する可能性があります。

    最大アクティブ同時実行文数

    同時実行 SQL 文の最大数。

    説明

    このパラメーターは、[ルールタイプ] パラメーターが [アクティブな同時実行文のスロットリング] に設定されている場合にのみ必須です。

    接続ごとの最大 QPS

    各接続の最大 QPS。

    説明

    このパラメーターは、[ルールタイプ] パラメーターが [接続ごとの QPS のスロットリング] に設定されている場合にのみ必須です。

仕組み

SQL スロットリング機能は PolarProxy 側で実行されます。 PolarProxy にさまざまなスロットリングルールを設定することで、特定の SQL 文の同時実行数または QPS を管理し、データベースクラスタの読み取り/書き込みノードまたは読み取り専用ノードに追加の影響が及ぼされないようにします。 この機能は、クラスタエンドポイントまたはカスタムエンドポイントに対してのみ構成できます。

SQL テンプレートとマッチングモード

テンプレートマッチングと全文一致

SQL テンプレートは、PolarDB for PostgreSQL (Oracle 互換) クラスタの標準構文に準拠している必要があります。 SQL テンプレートが構成されると、PolarProxy は選択されたマッチングモードに基づいてさまざまな前処理ステップを適用します。

  • 以下の SQL テンプレートで構成されたスロットリングルールを考えてみます。

    SELECT * FROM tbl WHERE id < 1;
    • テンプレートマッチングの場合、SQL テンプレートは、余分なスペースとコメントを削除し、単一引用符で囲まれた文字列や数値などの定数をワイルドカード文字に置き換えることによって正規化されます。 次の結果が得られます。

      -- テンプレート結果
      SELECT * FROM tbl WHERE id < ?
    • 全文一致の場合、SQL テンプレートも正規化されますが、定数は置き換えられません。 次の結果が得られます。

      -- フォーマット済み結果のみ
      SELECT * FROM tbl WHERE id < 1

    PolarProxy は、後続のマッチングのために、フォーマットされた SQL 文の一意の識別子を生成します。

  • スロットリングルールがアクティブな場合、PolarProxy は SQL テンプレートと同様の方法で受信する各 SQL 文を前処理します。 以下の SQL 文を考えてみます。

    SELECT * FROM tbl WHERE id < 100;

    次に、2 つのフォーマットされた SQL 文が生成され、一意の識別子が計算され、システムはスロットリングルールとの一致を試みます。

    -- テンプレート結果
    SELECT * FROM tbl WHERE id < ?
    
    -- フォーマット済み結果のみ
    SELECT * FROM tbl WHERE id < 100

SQL スロットリングルールを有効にすると、PolarProxy は現在の SQL 文を処理する前に既存のスロットリングルールを調べます。 テンプレートマッチングモードの場合、SQL を構成済みのテンプレートと比較します。 全文一致モードの場合、SQL 文をルールで指定されたフォーマット済みテンプレートと照合します。 ルールが一致すると、システムは同時実行文または QPS を記録し、適切なスロットリング操作を実行します。

したがって、上記の SQL 文と SQL テンプレートは、テンプレートマッチングが構成されている場合にのみルールにヒットします。

パラメーター化クエリ

SQL テンプレートは、PostgreSQL の標準パラメーターバインディング構文に準拠したパラメーター化クエリをサポートします。

SELECT * FROM tbl WHERE id < $1 AND name = $2 LIMIT 1;

パラメーター化されたセクションは、テンプレートマッチングと全文一致の両方でワイルドカード文字としてフォーマットされます。

-- テンプレート結果
SELECT * FROM tbl WHERE id < ? AND name = ? limit ?

-- フォーマット済み結果のみ
SELECT * FROM tbl WHERE id < ? AND name = ? limit 1

以下の SQL 文の場合:

SELECT * FROM tbl WHERE id < $1 AND name = 2 LIMIT 100;

現在のモードは、テンプレートマッチングが使用されている場合は指定されたルールにヒットしますが、全文一致が使用されている場合はヒットしません。

説明

パラメーター化クエリのために SQL テンプレートで ? 記号を使用することはサポートされていません。

-- 無効な SQL テンプレート。 標準の PostgreSQL 構文に準拠していないため、SQL 文はルールにヒットしません。
SELECT ?, ?, ?;

-- 有効な SQL テンプレート。
SELECT $1, $2, $3;

プリペアドステートメント

ビジネスオペレーションでプリペアドステートメントを使用する場合、PREPARE 文はスロットリングをトリガーしません。 Execute 文のみがトリガーします。 Execute フェーズでは、PREPARE 文の SQL 文がフォーマットまたはテンプレート化され、指定されたルールと照合されます。

説明

プリペアドステートメントの詳細については、「PREPARE」をご参照ください。

以下の SQL テンプレートを使用してスロットリングルールを構成し、テンプレートマッチングを選択します。

SELECT * FROM tbl WHERE id < $1 AND name > $2;

以下のビジネス SQL 文の場合:

-- PREPARE 文はスロットリングをトリガーしません。
PREPARE s1 AS SELECT * FROM tbl WHERE id < $1 AND name > 100;

-- EXECUTE 文は、PREPARE 文の SQL 部分を使用してスロットリングルールと照合します。
EXECUTE s1;

EXECUTE s1;

EXECUTE s1;

3 つの Execute 文は、スロットリングルールとスロットリング操作をトリガーします。

同様に、スロットリングルールの SQL テンプレートに PREPARE 文を組み込むと、PREPARE 文内の SQL 部分のみがスロットリングのためにフォーマットまたはテンプレート化されます。 ルールを作成するための以下の 2 つの SQL テンプレートは同等です。

-- テンプレート 1
PREPARE s1 AS SELECT * FROM tbl WHERE id < $1 AND name > $2;

-- テンプレート 2
SELECT * FROM tbl WHERE id < $1 AND name > $2;

拡張クエリ

PREPARE 文と同様に、ビジネスドライバーが拡張プロトコルを使用する場合、スロットリングは Execute メッセージによってのみ開始されます。 各 Execute メッセージは、対応する Parse メッセージと照合されて SQL テンプレートが計算され、スロットリングルールが適用されるかどうかが判断されます。 その結果、SQL スロットリングは拡張プロトコルと互換性があり、通常、ビジネスで使用されるプロトコルについて特別な考慮は必要ありません。

説明

拡張プロトコルの詳細については、「ドキュメント」をご参照ください。

制限事項

SQL スロットリング機能には、以下の制限があります。

  • スロットリングは、複数文トランザクションをサポートしていません。 複数文が使用されている場合、スロットリングルールは有効になりません。

    複数文とは、単一の SQL テキスト内でセミコロンで区切られた一連の SQL 文です。 JDBC ドライバーを介して複数文を実行する例を以下に示します。

    Statement statement = connection.createStatement();
    
    statement.execute("select 1; select 2; select 3");

    複数文の実行により、一度に複数のスロットリングルールがトリガーされる可能性があります。 予期しない結果を防ぐために、複数文の実行に対してはスロットリングは実装されていません。

  • トランザクション制御文やストアドプロシージャなど、一部の特殊な文はスロットリングの対象外です。 たとえば、COMMIT などのトランザクション制御文にスロットリングを適用すると、トランザクションが実行されない可能性があります。 したがって、スロットリングルールから除外されます。

  • クライアントまたはドライバーで使用される文のバッチモードでは、実行された SQL 文に対して最初にヒットしたスロットリングルールのみがトリガーされます。 JDBC ドライバーを介したバッチ実行の例を以下に示します。

    Statement statement = connection.createStatement();
    
    statement.addBatch("select 1");
    statement.addBatch("select 2");
    statement.addBatch("select 3");
    
    int[] result = statement.executeBatch();
    statement.close();
    connection.close();

    複数文の実行と同様に、文のバッチ処理では、複数の SQL 拡張プロトコルメッセージが 1 つの送信に結合されることが多く、複数のスロットリングルールが同時にトリガーされる可能性があります。 そのような場合、最初にヒットしたスロットリングルールのみが適用されます。 上記の例で、エンドポイントに 3 つの SQL テンプレートのスロットリングルールが構成されている場合:

    -- テンプレート 1
    SELECT 1;
    
    -- テンプレート 2
    SELECT 2;
    
    -- テンプレート 3
    SELECT 3;

    最初のテンプレートルールのみがトリガーされます。

  • SQL テンプレートは、大文字と小文字を区別しないキーワードをサポートしていません。 SQL テンプレートを設定する場合、大文字と小文字は、スロットリングされる SQL テキストの大文字と小文字と一致する必要があります。

  • SQL テンプレートは、in/any 句などの要素の数を無視する可変長式もサポートしていません。 例:

    -- SQL テンプレート
    SELECT * FROM tbl WHERE id IN ($1, $2, $3);
    
    -- SQL1、テンプレートにヒット可能
    SELECT * FROM tbl WHERE id IN (1, 6, 8);
    
    -- SQL2、テンプレートにヒット不可
    SELECT * FROM tbl WHERE id IN (1, 6, 8, 8);
  • 最初にスロットリングルールが構成されていない場合、新しく追加されたスロットリングルールは既存の接続には適用されません。 ただし、コンソールにスロットリングルールが存在する場合(有効かどうかにかかわらず)、新しい追加、変更、または削除はすべての接続にすぐに適用されます。

    説明
    • ビジネスが持続的接続に依存しており、新しいルールをすぐに有効にする必要がある場合は、関連するエンドポイントにプレースホルダーのルールを設定し、無効にしておくことをお勧めします。 これにより、後続の追加または変更を新規および既存の両方の接続に適用できます。

    • PolarProxy 2.3.58 以降を使用している場合、スロットリングルールの追加、変更、削除はすべての接続にリアルタイムで反映されます。 PolarDB コンソールで PolarProxy のバージョンを確認できます。 バージョンが要件を満たしていない場合は、 PolarProxy のバージョンを更新してください。

スロットリング方法

SQL テンプレートと待機キューは、QPS または SQL 文の同時実行数に基づく SQL スロットリングに使用されます。 ビジネス SQL が事前定義されたスロットリングルールにヒットすると、QPS または SQL 文の同時実行数のカウントがトリガーされます。 QPS または SQL 文の同時実行数のしきい値に達すると、PolarProxy は SQL 文を待機キューに配置します。 PolarProxy は、指定された期間が経過した後、しきい値を超えないようにして、文の再実行を試みます。

待機キューの遅延間隔は、ルールで指定された QPS または SQL 文の同時実行数に反比例します。 ルールの待機キューの最大長を超えると、PolarProxy は SQL 文を処理せず、クライアントに以下のエラーを返します。

SELECT 123;
現在のクエリはスロットリングされており、待機キューがいっぱいです。
説明

上記のエラーは、現在の接続のトランザクション解決プロセスを中断または変更しません。 エラーが返された後も、クライアントはトランザクションをコミットするかロールバックするかを決定できます。

さらに、SQL スロットリングルールで最大同時実行文数または接続ごとの最大 QPS が 0 に設定されている場合、ルールに一致する SQL 文は拒否され、クライアントはすぐに上記のエラーを受け取ります。 このアプローチにより、特定の種類の SQL 文の実行を効果的にブロックできます。

説明
  • 待機キューには最小再試行間隔があります。 最大 QPS が高い場合、実際の QPS は構成値よりもわずかに低くなる可能性があります。

  • SQL スロットリングルールが構成されると(ヒットするかどうかは関係ありません)、PolarProxy はビジネス SQL 文ごとに、テンプレート化、一意の識別子の生成、ルールとの一致の試みなど、いくつかの操作を実行します。 その結果、SQL スロットリングを有効にすると、転送パフォーマンスが 5% ~ 10% 低下する可能性があります。 SQL スロットリングは、データベース側の低速の SQL クエリが通常のビジネスオペレーションに影響を与える場合にのみ使用できます。 低速の SQL クエリの問題が解決したら、コンソールでスロットリングルールを無効にできます。 無効化されたルールは無効になりますが、将来使用するために保持されます。 いつでも有効にできます。

ベストプラクティス

スロットリングルールが有効かどうかをテストする

スロットリングルールは特定のアカウントとデータベースに適用できるため、新しいアカウントを確立し、スロットリングルールを構成し、最大同時実行文数または接続ごとの最大 QPS を 0 に設定できます。 スロットリングルールが有効かどうかを確認します。

以下の SQL 文を考えてみます。

SELECT * FROM generate_series(1, 100000);
  1. アカウントを作成する

    image

  2. テストアカウントのスロットリングルールを構成し、最大同時実行文数を 0 に設定します。 詳細については、「手順」をご参照ください。

    image

  3. ルールが有効であることを確認します。 ルールはテストアカウントにのみ適用され、進行中の操作には影響しません。 ルールを作成した後、指定されたエンドポイントを使用してデータベースに接続し、SQL 文を実行します。 以下のエラーメッセージが返された場合、ルールは有効です。

    SELECT * FROM generate_series(1, 100000);
    現在のクエリはスロットリングされており、待機キューがいっぱいです。

本番環境で低速の SQL クエリを処理するために SQL スロットリングを使用する

  1. テスト環境をセットアップします。

    • ECS インスタンスを準備します。

      1. CentOS 7.6 64 ビットなどの Linux オペレーティングシステムを使用して ECS インスタンスを作成します。 詳細については、「カスタム購入インスタンス」をご参照ください。

        説明

        ECS インスタンスと PolarDB クラスタは、同じゾーンと VPC に配置することをお勧めします。

      2. ECS インスタンスに pgbench ツールをインストールします。

        sudo yum install postgresql-contrib
    • PolarDB クラスタを準備します。

      1. PolarDB クラスタ購入ページ にアクセスして、クラスタを作成する

      2. データベースアカウントを作成する

      3. エンドポイントを表示または申請するPolarDB クラスタと ECS が同じゾーンにある場合は、プライベート IP アドレスを直接使用できます。 それ以外の場合は、パブリック IP アドレスをリクエストする必要があります。 ECS インスタンスの IP アドレスを PolarDB クラスタホワイトリストに追加します。 詳細については、「クラスタのホワイトリストを構成する」をご参照ください。

      4. データベースを作成する

      5. 後続で構成されたスロットリングルールが既存の接続に確実に反映されるように、コンソールでルールを構成して無効にします。 詳細については、「手順」をご参照ください。

        説明

        PolarProxy 2.3.58 以降を使用している場合、スロットリングルールの追加、変更、削除はすべての接続にリアルタイムで反映されます。 PolarDB コンソールで PolarProxy のバージョンを確認できます。 バージョンが要件を満たしていない場合は、 PolarProxy のバージョンを更新してください。

        image

  2. ECS インスタンスで、pgbench ツールを使用して PolarDB クラスタエンドポイントに接続し、テストデータを準備します。

    pgbench -h <PolarDB クラスタアドレス> -p <PolarDB クラスタアドレスポート> -i -s 10 -U <PolarDB データベース ユーザー名> <テストデータベース名>

    次に、pgbench の tpcb-like モードでテストを開始し、一般的なビジネスワークロードをシミュレートします。

    pgbench -h <PolarDB クラスタアドレス> -p <PolarDB クラスタアドレスポート> -P 1 -b tpcb-like -j 5 -c 10 -M prepared -T 6000 -U <PolarDB データベースユーザー名> <テストデータベース名> 
  3. 低速の SQL クエリのシナリオをシミュレートします。 新しい接続セッションを作成し、テストデータベースで以下の文を実行します。

    WITH t AS (SELECT md5(i::text) AS id FROM generate_series(1, 10000000) i) SELECT * FROM t ORDER BY id LIMIT 1;

    この SQL クエリはリソースを大量に消費し、通常、結果が得られるまでに約 5 秒かかります。

                    id                
    ----------------------------------
     0000023f507999464aa2b78875b7e5d6
    (1 row)

    pgbench を再起動し、カスタムスクリプトを使用して上記の SQL 文のテストを実施します。 10 個の接続を開始して、低速の SQL クエリによって高負荷が発生する状況をエミュレートします。

    echo "WITH t AS (SELECT md5(i::text) AS id FROM generate_series(1, 10000000) i) SELECT * FROM t ORDER BY id LIMIT 1;" > slow.sql
    
    pgbench -h <PolarDB クラスタアドレス> -p <PolarDB クラスタアドレスポート> -P 1 -f slow.sql -j 5 -c 10 -M prepared -T 6000 -U <PolarDB データベースユーザー名> <テストデータベース名> 

    テストを開始すると、標準のビジネスワークロードが大幅に低下します。

  4. コンソールで、以下の SQL テンプレートを使用してスロットリングルールを構成し、[ルールタイプ] を [アクティブな同時実行文のスロットリング] に設定します。

    WITH t AS (SELECT md5(i::text) AS id FROM generate_series($1, $2) i) SELECT * FROM t ORDER BY id LIMIT $3;

    image

    [最大アクティブ同時実行文数] パラメーターを 1 に設定します。 ルールが有効になると、ビジネスワークロードの増加が観察され、スロットリングルールがアクティブであることが示されます。

  5. コンソールで、ルールの対応する [操作] 列の [変更] をクリックして、スロットリングルールを調整します。 [最大アクティブ同時実行文数] パラメーターを 0 に設定して、低速の SQL クエリを完全にブロックします。

    image

    変更後、低速の SQL クエリテストが中断され、エラーメッセージが返されることがわかります。 ビジネスワークロードは再び高くなります。