このトピックでは、超大規模トランザクションのPolarDB-Xのパフォーマンスについて説明します。
分散データベースの場合、超大規模トランザクションは次の要件の1つ以上を満たします。
- 複数のシャードのデータがトランザクションで更新されます。
- トランザクションでは大量のデータが更新されます。
- トランザクションでは、多数のSQL文が実行されます。
このトピックでは、超大規模トランザクションのPolarDB-Xのパフォーマンスをテストするために、前述の要件の1つ以上を満たす複数のシナリオについて説明します。
テストのインスタンス仕様
次の表に、このトピックのテストに使用されるPolarDB-Xインスタンスを示します。
| PolarDB-Xのバージョン | polarx-kernel_5.4.11-16301083_xcluster-20210805 |
| ノード仕様 | 4 CPUコアと16 GBのメモリ |
| ノード数 | 4 |
テストを実行するために、4つのCPUコアと16 GBのメモリを備えたElastic Compute Service (ECS) インスタンスを作成します。 ECSインスタンスとPolarDB-Xインスタンスは同じCIDRブロックにあり、同じvSwitchで接続されています。
次のコマンドを実行して、tbという名前のテーブルを作成します。
CREATE TABLE 'tb' (
'id' bigint(20) NOT NULL、
'c' longblob/char(255)/char(1) 、
主要なキー ('id')
); このテーブルには、id列とc列の2つの列があります。 id列は、tbテーブルの主キー列です。 id列のデータ型はbigintです。 さまざまなシナリオでは、c列のデータ型はlongblob、char(255) 、char(1) です。 テーブルは、さまざまなシナリオで次の数のシャードに分割されます。
- 1つのシャード: テーブルに含まれるシャードは1つだけです。 PolarDB-Xは、シャード内のトランザクションコミットを1フェーズコミットとして最適化します。
- 8つのシャード: テーブルはid列に基づいて8つのシャードに分割され、各データノードに2つのシャードがあります。
- 16シャード: テーブルはid列に基づいて16のシャードに分割され、各データノードに4つのシャードがあります。
シナリオ 1
このシナリオでは、大量のデータを含む適度な数のSQL文が実行されます。 テーブルに書き込まれるデータの総量は多くなります。
| 実行されたSQL文の数 | 2,048 |
| 各SQL文に含まれるデータ量 | 256 KBから8 MB |
| 更新されたデータの量 | 512 16 GBへのMB |
| 更新されたデータの数 | 2,048 |
このシナリオで実行されるすべてのSQL文は、次の形式です。
INSERT INTO 'tb' VALUES (id, c)c列のデータ型はlongblobです。 列のデータのサイズは256 KB〜8 MBです。 したがって、トランザクションで2,048のSQL文が実行されると、合計512 MB〜16 GBのlongblobデータがテーブルに書き込まれます。 テーブルに書き込まれる実際のデータ量は、書き込まれるlongblobデータの量よりも大きくなります。これは、bigint型であるid列のデータもテーブルに書き込まれるためです。
非シャードデータベースの場合、c列に書き込まれた各データのサイズが1 MBの場合、トランザクションに書き込まれたデータの合計量が2 GBを超えると、次のエラーが報告されます。
ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] GROUP... で実行するとエラーが発生します。マルチステートメントのトランザクションには 'max_binlog_cache_size 'バイト以上のストレージが必要です。このmysqld変数を増やして再試行トランザクションでは、binlogに書き込まれるデータの量は、MAX_BINLOG_CACHE_SIZEパラメータで指定されるデータノードの制限を超えることはできません。 分散トランザクションの場合、各ブランチトランザクションは1つのシャードで実行され、binlogに書き込まれるデータ量は、MAX_BINLOG_CACHE_SIZEパラメーターで指定されるデータノードの制限を超えることはできません。 このシナリオでは、2,048 SQL文がすべてINSERT文の場合、各シャードに書き込まれるデータ量は2 GBを超えることはできません。 したがって、トランザクションでデータベースに書き込まれるデータの合計量は、(シャード数 × 2 GB) を超えることはできません。 たとえば、シャードが8つあるデータベースの場合、トランザクションでデータベースに書き込まれたデータの合計量が16 GBを超えると、前述のエラーが報告されます。 ただし、トランザクションでデータベースに書き込まれるデータ量が (シャード数 × 2 GB) よりも少ない場合でも、トランザクションが成功することは保証されません。
- トランザクションが開始されるかどうかに関係なく、各SQL文に含まれるデータ量はMAX_ALLOWED_PACKETの値を超えることはできません。
- トランザクションごとに、各シャードでSQL文が実行されたときにbinlogに書き込まれるデータの量は、データノードの制限を超えることはできません。 たとえば、INSERTステートメントを実行してデータをシャードに書き込むと、シャードに書き込まれたデータもbinlogに記録されます。 したがって、binlogに記録されたデータ量がMAX_BINLOG_CACHE_SIZEの値を超えないようにするために、トランザクションの各シャードに書き込まれるデータはこの値を超えることはできません。
- より多くのデータを挿入するなど、トランザクションでより多くのデータを操作する場合は、テーブルをより多くのシャードに分割します。
シナリオ 2
このシナリオでは、少数のSQL文が実行されます。 各ステートメントには少量のデータが含まれています。 トランザクションによって大量のデータがテーブルに書き込まれます。
| 実行されたSQL文の数 | 1 |
| 各SQL文に含まれるデータ量 | 約256 KB |
| 更新されたデータの量 | 256 MBから8 GB |
| 更新されたデータの数 | 1,048,576 (2 ^ 20) から33,554,432 (2 ^ 25) |
このテストでは、c列のデータ型はchar (255) です。 33,554,432のデータをテーブルにインポートします。 id列の値は、0から2 ^ 26-1までの連番です。 c列の各値は、連続255文字「a」からなる文字列である。 次に、トランザクションを開始し、次のSQL文を実行します。
UPDATE 'tb' SET c=255の連続した文字 "B" で構成される文字列 (id < ?)それを仮定しますか? ステートメントでは、xの値を示します。 SQL文が実行された後、x個のデータが更新され、データごとに256バイトのデータが更新されます。 したがって、データの総量はx * 2 ^ 8バイトである。 このテストでは、xの値は1,048,576 (2 ^ 20) から33,554,432 (2 ^ 25) の範囲であり、更新されたデータの合計量は512 MBから8 GBです。
非シャードテーブルの場合、xの値が4,194,304 (2 ^ 22) の場合、トランザクションの更新データの合計量が約1 GBを超えると、次のエラーが報告されます。
ERR-CODE: [TDDL-4614][ERR_EXECUTE_ON_MYSQL] GROUP... で実行するとエラーが発生します。マルチステートメントのトランザクションには 'max_binlog_cache_size 'バイト以上のストレージが必要です。このmysqld変数を増やして再試行UPDATE文を実行してシャード内のデータを更新すると、更新前後のデータがすべてbinlogに記録されます。 したがって、UPDATE文を実行して256バイトのデータを更新すると、少なくとも512バイトのデータがbinlogに記録されます。 非シャードデータベースの場合、1 GBのデータが更新されると、binlogに記録されたデータが2 GBを超えるため、前述のエラーが報告されます。 同様に、分散トランザクションの場合、UPDATEステートメントのみが実行される場合、各シャードで更新されるデータ量は1 GBを超えることはできません。 たとえば、このシナリオでテーブルが8つのシャードに分割されている場合、トランザクションで8 GBのデータが更新されると、前述のエラーが報告されます。
テストの結論- シナリオ1の結論と同様に、トランザクションの場合、各シャードでSQL文が実行されたときにbinlogに書き込まれるデータの量は、MAX_BINLOG_CACHE_SIZEパラメーターで指定されるデータノードの制限を超えることはできません。 たとえば、トランザクションにUPDATE文のみが含まれる場合、更新前後のデータはすべてbinlogに記録されます。 この場合、各シャードの更新データ量は、MAX_BINLOG_CACHE_SIZEパラメータの値の半分を超えることはできません。 このシナリオでは、テーブルがシャードされていない場合、トランザクションで更新されるデータ量は1 GBを超えることはできません。 テーブルが8つのシャードに分割されている場合、トランザクションで更新されるデータ量は4 GBを超えることはできません。
- より多くのデータを挿入するなど、トランザクションでより多くのデータを操作する場合は、テーブルをより多くのシャードに分割します。
シナリオ 3
このシナリオでは、大量のSQL文が実行されます。 各ステートメントには少量のデータが含まれています。 トランザクションによって少量のデータが書き込まれる。
| 実行されたSQL文の数 | 1,280,000に64,000 |
| 各SQL文に含まれるデータ量 | 数バイト |
| 更新されたデータの量 | 32B |
| 更新されたデータの数 | 32 |
このテストでは、c列のデータ型はchar (1) です。 32個のデータをテーブルに挿入します。 id列の値は0から31までの連番です。 c列の各値は「a」文字です。 次に、トランザクションを開始して、次のステートメントをx回実行します。 各トランザクションは64x SQL文を実行します。
UPDATE 'tb' SET c = "b" (id = 0);
UPDATE 'tb' SET c = "a" id = 0;
UPDATE 'tb' SET c = "b" (id = 1)
UPDATE 'tb' SET c = "a" ここでid = 1;
...
UPDATE 'tb' SET c = "b" (id = 31);
UPDATE 'tb' SET c = "a" ここでid = 31; テストの結論このシナリオでは、テーブルが分割されるシャードの数に関係なく、トランザクションで1.28万個のSQL文が実行されても、PolarDB-Xインスタンスのパフォーマンスはボトルネックになりません。 したがって、同様のシナリオでは、PolarDB-Xのパフォーマンスは、書き込まれる、削除される、または更新されるデータの量によってボトルネックになる可能性が高くなります。
シナリオ 4
このシナリオは、シャードの数がトランザクションのパフォーマンスにどのように影響するかをテストします。
| 実行されたSQL文の数 | 1 |
| 各SQL文に含まれるデータ量 | 数バイト |
| 更新されたデータの量 | 8 KBから8 MB |
| 更新されたデータの数 | 8 KBから8 MB |
| シャードの数 | 1から2,048 |
このシナリオでは、c列のデータ型はchar (1) です。 テーブルにx個のデータを挿入します。 id列の値は、0からxまでの連番です。 c列の各値は、文字「a」である。 次に、トランザクションを開始し、次のステートメントを実行します。 各トランザクションは、x個のデータおよびxバイトのデータを更新する。
UPDATE 'tb' SET c = "b" ここでid < xトランザクションで前のSQL文が実行されるたびに、x個のデータが更新され、更新されたデータの量はxバイトになります。
テストの結論- 更新データ量が8 KBの場合, データ量が少ないため, SQL文の実行時間が短くなります。 したがって、トランザクションコミット時間はトランザクション実行時間に大きな影響を与えます。 この場合、トランザクションの実行時間は、シャードの数が増加するにつれて増加する。 しかしながら、シャードの数が1から64の範囲内で増加する場合、トランザクション実行時間は、シャードの数に比例して増加しない。 これは、トランザクションのコミット時間に加えて、小さな範囲内でシャードの数が増加しても、DMLステートメントの実行時間がトランザクションの実行時間に影響を与えるためです。 シャードの数が1,024から2,048の範囲で増加すると、トランザクションの実行時間はトランザクションのコミット時間によって決まります。 この場合、トランザクションコミット時間と比較して、DMLステートメントの実行時間は、トランザクションの実行時間にほとんど影響を与えません。 したがって、トランザクションの実行時間は、シャードの数に比例して増加します。
- 更新されたデータの量が8 MBの場合、トランザクションの実行時間はシャードの数によって増加しません。 代わりに、トランザクション実行時間はDMLステートメントの実行時間によって決定され、トランザクションコミット時間は無視できます。
- トランザクションで大量のデータを操作する必要がある場合は、テーブルをより多くのシャードに分割することをお勧めします。 ただし、テーブルをより多くのシャードに分割すると、トランザクションのコミット時間が長くなります。 少量のデータが多数のシャード上で操作されるトランザクションでは、トランザクション実行時間はトランザクションコミット時間によって決定されます。 したがって、トランザクションパフォーマンスを向上させるには、このトピックで提供されているテストの結論を参照し、実際のシナリオに基づいてテーブルを適切な数のシャードに分割します。
シナリオ 5
このシナリオは、計算ノードのワークロードがトランザクションパフォーマンスにどのように影響するかをテストするように設計されています。
手順このシナリオでは、論理テーブルtbは16個のシャードに分割される。 表のc列のデータ型はchar (255) です。 67,108,864 (2 ^ 26) 個のデータをテーブルに挿入します。 id列の値は0から2 ^ 26 - 1までの連番で、c列と同じです。 次に、テーブルtbとスキーマとデータが同じtb2という別のテーブルを作成します。 テーブルtb2のサイズは、テーブルtbと同じ16 GB程度である。 テーブルtbと同じスキーマを持つtmpという名前の一時テーブルを作成します。 次に、トランザクションを開始し、次のステートメントを実行します。
tmpに挿入
SELECT tb.id, tb.c
tbから、tb2
WHERE tb.c = tb2.c AND tb.id > x AND tb2.id > x EXPLAINステートメントを実行して、このSQLステートメントの実行計画を表示できます。
LogicalInsert(table="tmp" 、columns=RecordType(BIGINT id、CHAR c))
プロジェクト (id="id", c="c")
HashJoin(condition="c = c", type="inner")
収集 (concurrent=true)
LogicalView(tables="[000000-000015].tb_VjuI", shardCount=16, sql="SELECT 'id', 'c' FROM 'tb' AS 'tb' WHERE ('id' > ?)")
収集 (concurrent=true)
LogicalView(tables="[000000-000015].tb2_IfrZ", shardCount=16, sql="SELECT 'c' FROM 'tb2' AS 'tb2' WHERE ('id' > ?)") 実行計画に従って、このステートメントは、tbおよびtb2からidがxより大きいデータを選択し、計算ノード上の選択されたデータに対してハッシュ結合を実行します。 このステートメントでは、xパラメーターを設定して、計算ノードで選択および結合するデータの量を決定できます。 xが0に設定されると、tbおよびtb2のすべてのデータが選択され、結合される。 この場合、計算ノードは合計32 GBのデータを処理する必要があります。 参考までに、各計算ノードのメモリは16 GBです。
テストの結論PolarDB-Xは、計算ノードで実行する必要がある複雑な結合操作を伴うトランザクションなど、大量のデータを伴う単一のトランザクションによって計算ノードのワークロードが高い場合に安定したパフォーマンスを提供します。 具体的には、トランザクション実行時間は、データがエラーなしに処理されると線形レートで増加する。
概要
- トランザクションが開始されるかどうかに関係なく、各SQL文に含まれるデータ量は、MAX_ALLOWED_PACKETパラメーターの値を超えることはできません。
- 各トランザクションで、各シャードでSQL文が実行されたときにbinlogに書き込まれるデータの量は、MAX_BINLOG_CACHE_SIZEパラメーターで指定されたデータノードの制限を超えることはできません。
- デフォルトでは、パラメーターの値は2 GBです。 MySQLの制限により、最大値は4 GBです。 たとえば、INSERTステートメントのみを含むトランザクションの場合、binlogには挿入された値が記録されるため、データベースに書き込まれるデータの合計量は (シャード数x 4 GB) を超えることはできません。
- より多くのデータを挿入、削除、更新するなど、トランザクションでより多くのデータを操作する場合は、テーブルをより多くのシャードに分割します。
- 更新されたデータの量が少ない場合、シャードの数はトランザクションの実行時間に大きな影響を与えます。 それ以外の場合、シャードの数はトランザクションの実行時間にほとんど影響を与えません。 したがって、トランザクションパフォーマンスを向上させるには、このトピックで提供されているテストの結論を参照し、実際のシナリオに基づいてテーブルを適切な数のシャードに分割します。
- PolarDB-Xは、大量のデータを伴う単一のトランザクションによって計算ノードのワークロードが高い場合に安定したパフォーマンスを提供します。