PolarDBのステートメントキュー機能を使用すると、同じバケット内で競合する可能性のあるステートメントをキューに入れることができます。 これは起こり得る衝突からのオーバーヘッドを減らす。
背景情報
同時ステートメントの実行中に、MySQLサーバーとエンジンは、いくつかのシリアル操作で互いに競合する可能性があります。 たとえば、トランザクションロックは、データ操作言語 (DML) ステートメントでは一般的です。 InnoDBでは、行はロックできる最小単位であり、行レベルのロックはトランザクションロックの最小ロック粒度です。 ステートメントが同じ行で同時に実行されると、競合が発生する可能性があり、同時実行が増加するにつれてシステムスループットが低下する可能性があります。 PolarDBが提供するステートメントキュー機能は、これらの競合によるオーバーヘッドを減らし、データベースのパフォーマンスを向上させます。
制限事項
- 次のPolarDBクラスターのいずれかを使用する必要があります。
- マイナーエンジンバージョンが8.0.1.1.10以降のPolarDB for MySQL 8.0のクラスター。
- マイナーエンジンバージョンが5.7.1.0.6以降のPolarDB for MySQL 5.7のクラスター。
- マイナーエンジンバージョンが20200601以降のPolarDB for MySQL 5.6のクラスター。
- PolarDB for MySQL 5.6とPolarDB for MySQL 5.7および8.0は、異なる構文を使用してステートメントキュー機能を実装します。 PolarDB for MySQL 5.7および8.0クラスターを使用する場合、ステートメントキューはステートメントアウトラインと連携して、同時SQLステートメント数のオンライン管理をサポートできます。
- hotspotをONに設定してホット行最適化機能を有効にすると、ステートメントキューのメカニズムは無効になります。
Effect
同時UPDATEステートメントが1行で実行されるシナリオテストでは、PolarDBのパフォーマンスはネイティブMySQLのパフォーマンスの約4倍です。
構文
- PolarDB for MySQL 5.6では、次のいずれかの方法を使用して、ハッシュアルゴリズムを使用してバケット内のステートメントをキューに入れることができます。 説明 SELECT、UPDATE、INSERT、およびDELETEステートメントで
POLARDB_STATEMENT_CONCURRENT_QUEUE
を使用できます。- INTまたはSTRING値に基づくバケット内のキューステートメント。
- 構文:
POLARDB_STATEMENT_CONCURRENT_QUEUE [int | string]
- 例:
t値 (1, 1, 'xpchild ') にPOLARDB_STATEMENT_CONCURRENT_QUEUE 1を挿入します。update POLARDB_STATEMENT_CONCURRENT_QUEUE 1 t set c=c + 1 (id = 1); update "xpchild" t set col1 = col1 + 1 (id =1);
- 構文:
- WHERE句のフィールド値に基づくバケット内のキューステートメント。
- 構文:
POLARDB_STATEMENT_CONCURRENT_QUEUE [field]
- 例:
select POLARDB_STATEMENT_CONCURRENT_QUEUE id * from t where 3 = id; update POLARDB_STATEMENT_CONCURRENT_QUEUE id t set c=c + 1 (id = 1、name = 'xpchild ');
説明POLARDB_STATEMENT_CONCURRENT_QUEUE [field]
構文では、元の列に対するバイナリ操作のみがWHERE句でサポートされています。 バイナリ演算の右側の値は、数値または文字列でなければなりません。 関数や計算は、これらの元の列では使用できません。
- 構文:
- INTまたはSTRING値に基づくバケット内のキューステートメント。
- PolarDB for MySQLの5.7と8.0では、次のいずれかの方法をヒント構文で使用して、バケット内のステートメントをキューに入れることができます。 説明 SELECT、UPDATE、INSERT、およびDELETEステートメントで
ccl_queue_value
を使用できます。- INTまたはSTRING値に基づくバケット内のキューステートメント。
- 構文:
/* + CCL_QUEUE_VALUE([INT | STRING)] */
- 例:
/* + ccl_queue_value(1) */ t set c=c + 1 (id = 1); update /* + ccl_queue_value('xpchild') */ t set c=c + 1 name = 'xpchild';
- 構文:
- WHERE句のフィールド値に基づくバケット内のキューステートメント。
- 構文:
/* + CCL_QUEUE_FIELD(STRING) */
- 例:
/* + ccl_queue_field("id") */ t set c=c + 1 id = 1およびname = 'xpchild ';
説明/* + CCL_QUEUE_FIELD(STRING) */
構文では、元の列に対するバイナリ操作のみがWHERE句でサポートされています。 バイナリ演算の右側の値は、数値または文字列でなければなりません。 関数や計算は、これらの元の列では使用できません。
- 構文:
- INTまたはSTRING値に基づくバケット内のキューステートメント。
変数
PolarDBは、バケットの数とステートメントキューのサイズを定義するために使用される次の変数を提供します。
変数 | 説明 |
ccl_queue_bucket_count | バケットの数。 有効な値: 1 ~ 64。 デフォルト値: 4。 |
ccl_queue_bucket_サイズ | バケットでサポートされている同時ステートメントの数。 有効な値: 1 ~ 4096 デフォルト値: 64。 |
操作
PolarDBは、ステートメントキューのステータスを照会するために使用される次の関数を提供します。
- dbms_ccl.show_ccl_queue()
この関数は、現在のステートメントキューのステータスを照会するために使用されます。
mysql> dbms_ccl.show_ccl_queue() を呼び出します。------ ------- ------------------- ----------------------------------------- | ID | TYPE | CONCURRENCY_COUNT | 一致 | 実行中 | 待機中 | ------ ------- ------------------- ----------------------------------------- | 1 | キュー | 64 | 1 | 0 | 0 | | 2 | キュー | 64 | 40744 | 65 | 6 | | 3 | キュー | 64 | 0 | 0 | 0 | | 4 | キュー | 64 | 0 | 0 | 0 | ------ ------- ------------------- ----------------------------------------- セットの4列 (0.01秒)
説明 次の表に、CONCURRENCY_COUNT、MATCHED、RUNNING、およびWAITTINGパラメーターを示します。- CONCURRENCY_COUNT: 同時ステートメントの最大数。
- MATCHED: ルールに一致するステートメントの総数。
- RUNNING: 同時実行ステートメントの数。
- WAITTING: キューで待機しているステートメントの数。
- dbms_ccl.flush_ccl_queue()
この関数は、ステートメントキューに関するデータをメモリから削除し、ステートメントキューのステータスを照会するために使用されます。
mysql> call dbms_ccl.flush_ccl_queue(); クエリOK、影響を受ける0行 (0.00秒) mysql> dbms_ccl.show_ccl_queue() を呼び出します。------ ------- ------------------- ----------------------------------------- | ID | TYPE | CONCURRENCY_COUNT | 一致 | 実行中 | 待機中 | ------ ------- ------------------- ----------------------------------------- | 1 | キュー | 64 | 0 | 0 | 0 | | 2 | キュー | 64 | 0 | 0 | 0 | | 3 | キュー | 64 | 0 | 0 | 0 | | 4 | キュー | 64 | 0 | 0 | 0 | ------ ------- ------------------- ----------------------------------------- セットの4列 (0.00秒)
ステートメントの概要を操作してオンライン更新をサポートする
PolarDB for MySQLの5.7および8.0では、ステートメントキューはステートメントアウトラインと連携して、同時SQLステートメントの数のオンライン管理をサポートできます。 これにより、アプリケーションコードの変更が最小限に抑えられます。 次の例では、Sysbenchを使用してupdate_non_index.luaスクリプトを実行します。
- テスト環境
- スキーマ
テーブル 'sbtest1' の作成 ( 'id' int(10) 符号なしNOT NULL AUTO_INCREMENT、 'k' int (10) unsigned NOT NULL DEFAULT '0', 'c' char(120) NOT NULL DEFAULT ''、 'pad'char (60) NOT NULL DEFAULT ''、 主要なキー ('id') 、 キー 'k_1 ' ('k') エンジン=InnoDB AUTO_INCREMENT=2デフォルト料金=utf8 MAX_ROWS=1000000;
- ステートメント
UPDATE sbtest1 SET c='xpchild 'WHERE id=0;
- スクリプト
/sysbench -- mysql-host= {$ip} -- mysql-port= {$port} -- mysql-db=テスト -- test=./sysbench/share/sysbench/update_non_index.lua -- oltp-tables-count=1 -- oltp_table_size=1 -- num-threads=128 -- mysql-user=u0
- スキーマ
- 手順
- オンラインモードでステートメントアウトラインを作成します。
mysql> CALL DBMS_OUTNN.add_optimizer_outline ('test', '', 1, ' /* + ccl_queue_field("id") */ ' 、 "UPDATE sbtest1 SET c='xpchild 'WHERE id=0"); クエリOK、影響を受ける0行 (0.01秒)
- 作成したステートメントアウトラインを表示します。
mysql> dbms_outln.show_outline() を呼び出します。------ -------- ------------------------------------------------------------------ ---------------------------------- -------------------------------- ------------------ --------------------------------------------- + | ID | スキーマ | DIGEST | タイプ | スコープ | POS | ヒント | ヒット | オーバーフロー | DIGEST_TEXT | ------ -------- ------------------------------------------------------------------ ---------------------------------- -------------------------------- ------------------ --------------------------------------------- + | 1 | test | 7b945614749e541e0600753367884acff5df7e7ee2f5fb0af5ea58897910f023 | OPTIMIZER | | 1 | /* + ccl_queue_field("id") */ | 0 | 0 | UPDATE 'sbtest1' SET 'c' = ? どこ 'id' = ? | ------ -------- ------------------------------------------------------------------ ---------------------------------- -------------------------------- ------------------ --------------------------------------------- + 1行セット (0.00秒)
- ステートメントのアウトラインが有効になっていることを確認します。
mysql> UPDATE sbtest1 SET c='xpchild 'WHERE id=0について説明します。---- ----------- --------------------------------------------------------------------------------------------------------------- | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | ---- ----------- --------------------------------------------------------------------------------------------------------------- | 1 | UPDATE | sbtest1 | NULL | range | PRIMARY | PRIMARY | 4 | const | 1 | 100.00 | Using where | ---- ----------- --------------------------------------------------------------------------------------------------------------- セットの1列、1警告 (0.00秒) mysql> 警告を表示します。+ ------ ------ + ----------------------------------------------------------------------------------------------------------------------------- + | レベル | コード | メッセージ | + ------ ------ + ----------------------------------------------------------------------------------------------------------------------------- + | 注 | 1003 | update /* + CCL_QUEUE_FIELD('id') */ 'test'.'sbtest1' set 'test'.'sbtest1'.'c' = 'xpchild' where ('test'.'sbtest1'.'id' = 0) | + ------ ------ + ----------------------------------------------------------------------------------------------------------------------------- + 1行セット (0.00秒)
- 使用されているステートメントキューのステータスを照会します。
mysql> dbms_ccl.show_ccl_queue() を呼び出します。------ ------- ------------------- ----------------------------------------- | ID | TYPE | CONCURRENCY_COUNT | 一致 | 実行中 | 待機中 | ------ ------- ------------------- ----------------------------------------- | 1 | キュー | 64 | 0 | 0 | 0 | | 2 | キュー | 64 | 0 | 0 | 0 | | 3 | キュー | 64 | 0 | 0 | 0 | | 4 | キュー | 64 | 0 | 0 | 0 | ------ ------- ------------------- ----------------------------------------- セットの4列 (0.00秒)
- テストを開始します。
sysbench -- mysql-host= {$ip} -- mysql-port= {$port} -- mysql-db=テスト -- test=./sysbench/share/sysbench/update_non_index.lua -- oltp-tables-count=1 -- oltp_table_size=1 -- num-threads=128 -- mysql-user=u0
- テスト結果を確認します。
mysql> dbms_ccl.show_ccl_queue() を呼び出します。------ ------- ------------------- ----------------------------------------- | ID | TYPE | CONCURRENCY_COUNT | 一致 | 実行中 | 待機中 | ------ ------- ------------------- ----------------------------------------- | 1 | キュー | 64 | 10996 | 63 | 4 | | 2 | キュー | 64 | 0 | 0 | 0 | | 3 | キュー | 64 | 0 | 0 | 0 | | 4 | キュー | 64 | 0 | 0 | 0 | ------ ------- ------------------- ----------------------------------------- セットの4列 (0.03秒) mysql> dbms_outln.show_outline() を呼び出します。------ --------- ---------- ---------------------------------------------------------------- --------------------------------------------- + | ID | スキーマ | DIGEST | タイプ | スコープ | POS | ヒント | ヒット | オーバーフロー | DIGEST_TEXT | ------ --------- ---------- ---------------------------------------------------------------- --------------------------------------------- + | 1 | test | xxxxxxxxx | OPTIMIZER | | 1 | /* + ccl_queue_field("id") */ | 115795 | 0 | UPDATE 'sbtest1' SET 'c' = ? どこ 'id' = ? | ------ --------- ---------- ---------------------------------------------------------------- --------------------------------------------- + 1行セット (0.00秒)
説明 クエリ結果に基づいて、合計115,795のステートメントがステートメントアウトラインのルールにヒットし、合計10,996のステートメントがステートメントキューのルールにヒットし、合計63のステートメントが同時に実行され、4つのステートメントがキューで待機しています。
- オンラインモードでステートメントアウトラインを作成します。