異なる種類のトランザクションのコミットにかかる時間はそれぞれ異なります。パフォーマンスチューニングでは、マシン間の分散トランザクションの割合をできるだけ低くすることが望ましいです。トランザクションモデルの最適化には、以下の点から取り組むことができます:
ビジネス全体のロジック。
具体的なトランザクションに細分化する。
複数テーブルおよび単一テーブルのトランザクションの割合、および各種SQLの実行頻度を把握する。
トランザクションタイプの統計
SQLの実行計画は、Local、Remote、Distribute、Uncertainの4種類に分類されます。そのうち、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などです。
ローカル以外の計画分析
plan_type = 0を除く、ローカル以外の計画のリクエストは、トランザクションがマシン間で行われる可能性が高く、単一マシン上のトランザクションと比較してパフォーマンスに一定の影響を与える可能性があります。以下のいずれかの状況に従って確認することができます:
Primary Zoneが単一Zone&単一Unitの場合。
Primary Zoneが単一Zone&複数Unitの場合。
Primary ZoneがRANDOMの場合。
プライマリゾーンが単一のゾーンおよび単一のユニットの場合
単一ユニットでデプロイされるシナリオにおいて、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の場合、特に対処する必要はありません。
プライマリゾーンが単一ゾーン&複数ユニットの場合
このシナリオでは、同一ゾーン内のOBServer間で自動的にパーティションロードバランシングが行われ、トランザクションのマシン間分散は高い確率で可能となります。マシン間トランザクションを回避するため、トランザクション内のステートメント実行状況を踏まえてテーブルグループを分割し、トランザクションが単一マシン上で実行されるようにします。
テーブルグループの使用方法は以下の通りです:
--パーティションなしのシナリオ
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を分割し、トランザクションのスタンドアロン実行を可能な限り保証します。詳細については、primary zoneが単一zoneおよび複数unitの場合を参照してください。
バッチインポートのシナリオでは、PDMLのパラレル実行機能(バージョン3.2以降)を最大限に活用します。
ロード状況に応じてネットワークスレッド数(
net_thread_count)を調整します。この構成パラメータのデフォルト値は0であり、プロセス起動後、現在のマシンのCPUコア数に基づいて、そのマシンで必要な数を自動的に計算します。計算式は次のとおりです:min(6, cpu_core/8)。実際の状況に応じて予想値を手動で調整し、プロセス再起動時に反映されます。
注意事項
V2.2.x以前のバージョンでは、第一段階コミットの最適化を有効にすることはできません。
V3.2.x以前のバージョンでは、本番環境でのPartition Groupの最適化は推奨されません。パフォーマンスチューニングによりパフォーマンスが向上します。