トランザクションのコミット時間は種類によって異なります。パフォーマンスチューニングでは、マシンをまたいだ分散トランザクションの割合をできるだけ低減することが望ましいです。トランザクションモデルの改善は、以下の観点から取り組むことができます:
業務全体のロジック。
具体的なトランザクション単位での詳細化。
複数テーブルおよび単一テーブルに対するトランザクションの割合、および各種SQLの実行頻度を把握すること。
トランザクションタイプ統計
SQLの実行計画は4種類に分類されます:Local、Remote、Distribute、Uncertainです。ここで、Localは現在のステートメントに関連するパーティションのリーダーがセッションが存在するマシンと同じであることを示し、Remoteは現在のステートメントに関連するパーティションのリーダーがセッションが存在するマシンと異なることを示します。DistributeおよびUncertainの計画では、リーダーとセッションの関係を特定できず、同一マシン上にある場合もあれば、複数のマシンにまたがっている場合もあります。
トランザクションのパフォーマンスに関しては、まず単一マシントランザクションを優先し、次に分散トランザクションを考慮します。実行計画のタイプ統計情報から、分散トランザクションの割合を大まかに推定し、チューニングのためのデータサポートを提供することができます。関連するSQLは以下のとおりです:
MySQL [oceanbase]> select plan_type, count(1) from gv$ob_sql_audit where
request_time > time_to_usec('2021-08-24 18:00:00') group by plan_type;
+-----------+----------+
| plan_type | count(1) |
+-----------+----------+
| 1 | 17119 |
| 0 | 9614 |
| 3 | 4400 |
| 2 | 23429 |
+-----------+----------+
4 rows in set
ここで、plan_type = 1、2、3はそれぞれLocal、Remote、Distributeの実行計画を表します。一般的に、0はplanのないSQLステートメントを表します。例えば、set autocommit=0/1、commitなどです。
Non-Local計画の分析
Non-Local計画のリクエスト(plan_type = 0を除く)は、高い確率でトランザクションのマシン間移動を引き起こし、単一マシントランザクションに比べてパフォーマンスに一定の影響を与えます。以下のケースを確認することができます:
Primary Zoneが単一Zone & 単一Unitの場合。
Primary Zoneが単一Zone & 複数Unitの場合。
Primary ZoneがRANDOMの場合。
Primary Zoneが単一Zone & 単一Unitの場合
単一UnitデプロイメントのシナリオでRemoteやUncertain計画が発生した場合、これは想定外のことです。原因は主に以下のいくつかの点が考えられます:
当該テナントのフォロワーに直接接続されています。実行計画のタイプ統計情報で確認できます。
アプリケーションはOBProxyに接続していますが、トランザクションの最初のSQLがOBProxyによって正しく転送されず、結果としてセッションとトランザクションが関連するパーティションのリーダーがマシンを跨いでしまいます。この場合、クラスタ内のすべてのOBProxyのログを確認する必要があります。重要なログ情報は以下のとおりです:
fail to caculate partition id, just use tenant server一部のパーティションがちょうどリーダー切り替えを行った直後で、OBServerまたはOBProxyが管理するLocation Cacheがまだ最新に更新されていない場合。
ケース1の場合、アプリケーションを変更してOBProxyに接続させる必要があります。ケース2の場合、現在のSQLが複雑すぎて、OBProxyがParser処理中にアクセスする必要があるパーティションを計算できず、そのためランダムに送信したことが原因です。この場合、SQLの書き方を調整し、パーティションキーを含める必要があります。ケース3の場合、処理は不要です。
Primary Zoneが単一Zone & 複数Unitの場合
このシナリオでは、同一Zone内のOBServerが自動的にパーティションのロードバランシングを行います。トランザクションのマシン間移動は高い確率で発生する可能性があります。マシン間トランザクションを避けるためには、トランザクション内のステートメントの実行状況を踏まえてTable Groupを分割し、可能な限りトランザクションを単一マシンで実行できるようにする必要があります。
Table Groupの使用方法は以下のとおりです:
--非パーティションシナリオ
create tablegroup tg1;
create table t1 (id1 int, id2 int) tablegroup tg1;
create table t2 (id1 int, id2 int) tablegroup tg1;
--HASHパーティション(MySQLモード)
create tablegroup tg2 partition by hash partitions 2;
create table pg_trans_test2_1(id1 int, id2 int)
tablegroup tg2 partition by hash(id1 % 2) partitions 2;
create table pg_trans_test2_2(id1 int, id2 int)
tablegroup tg2 partition by hash(id1 % 2) partitions 2;
--HASHパーティション(Oracleモード)
create tablegroup tg2 partition by hash partitions 2;
create table pg_trans_test2_1(id1 int, id2 int)
tablegroup tg2 partition by hash(id1) partitions 2;
create table pg_trans_test2_2(id1 int, id2 int)
tablegroup tg2 partition by hash(id1) partitions 2;
--RANGEパーティション(MySQLモード)
create tablegroup tg3
partition by range columns 1 (
partition p0 values less than (10),
partition p1 values less than(20));
create table pg_trans_test3_1(id1 int, id2 int) tablegroup tg3
partition by range columns(id1)
(partition p0 values less than (10),
partition p1 values less than(20));
create table pg_trans_test3_2(id1 int, id2 int) tablegroup tg3
partition by range columns(id1)
(partition p0 values less than (10),
partition p1 values less than(20));
--RANGEパーティション(Oracleモード)
create tablegroup tg3
partition by range columns 1
(partition p0 values less than (10),
partition p1 values less than(20));
create table pg_trans_test3_1(id1 int, id2 int)
tablegroup tg3 partition by range (id1)
(partition p0 values less than (10),
partition p1 values less than(20));
create table pg_trans_test3_2(id1 int, id2 int)
tablegroup tg3 partition by range (id1)
(partition p0 values less than (10),
partition p1 values less than(20));
--LISTパーティション (MySQLモード)
create tablegroup tg4 partition by list columns 1 (
partition p0 values in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
partition p1 values in (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
);
create table pg_trans_test4_1(id1 int, id2 int) tablegroup tg4 partition by list columns(id1) (
partition p0 values in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
partition p1 values in (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
);
create table pg_trans_test4_2(id1 int, id2 int) tablegroup tg4 partition by list columns(id1) (
partition p0 values in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
partition p1 values in (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
);
--LISTパーティション (Oracleモード)
create tablegroup tg4 partition by list columns 1 (
partition p0 values (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
partition p1 values (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
);
create table pg_trans_test4_1(id1 int, id2 int) tablegroup tg4 partition by list(id1) (
partition p0 values (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
partition p1 values (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
);
create table pg_trans_test4_2(id1 int, id2 int) tablegroup tg4 partition by list(id1) (
partition p0 values (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
partition p1 values (11, 12, 13, 14, 15, 16, 17, 18, 19, 20)
);
Primary ZoneがRANDOMの場合
RANDOMデプロイメントでは、テナントのテーブルリーダーがランダムに分散され、分散クロスマシントランザクションも同様に高い確率で発生します。
トランザクションコミットの最適化プラン
単一テーブル & 複数テーブルの単一マシントランザクション
OceanBase データベース V4.0 では、シングルログストリームアーキテクチャが調整されたことにより、トランザクションが関連するログストリームのリーダーが同一マシン上にある場合、デフォルトでシングルログストリームトランザクションが実行されます。このトランザクションモデルはパフォーマンスが最も高いため、設定項目の調整は不要です。
複数マシントランザクション
主に以下の 2 つの問題を解決します:
可能な限りマルチマシン機能を活用する。
OBServer のトラフィックロードバランシングを行う。
具体的な手段:
複数マシントランザクションを回避するため、トランザクション内のステートメント実行状況を踏まえて Table Group を分割し、トランザクションが単一マシンで実行されるようにする。詳細は プライマリゾーンが単一ゾーン & 複数ユニット を参照してください。
バッチインポートのシナリオでは、PDML の並列実行機能(バージョン 3.2 以降)を可能な限り活用する。
ロード状況に応じてネットワークスレッド数(
net_thread_count)を調整する。この構成パラメータはデフォルトで 0 であり、プロセス起動後、現在のマシンの CPU コア数に基づいて、そのマシンで必要な数が自動的に計算される。計算式は以下の通りです:min( 6, cpu_core/8 )。実際の状況に応じて、期待値を手動で調整し、プロセス再起動で変更が有効になります。
注意事項
V2.2.x およびそれ以前のバージョンでは、1段階コミットの最適化を有効にすることはできません。
V3.2.x およびそれ以前のバージョンでは、本番環境での Partition Group 最適化の使用は推奨されません。パフォーマンスチューニングによりパフォーマンスが向上する可能性があります。