この章では、ODPのテーブルルーティングメカニズムについて説明します。
OceanBaseデータベースでは、パーティションがデータストレージの基本単位です。テーブルを作成すると、テーブルとパーティションのマッピングが存在します。非パーティションテーブルの場合、1つのテーブルは1つのパーティションに対応し、パーティションテーブルの場合、1つのテーブルが複数のパーティションに対応する可能性があります。現在、OceanBaseデータベースではパーティションのコンパクションとスプリットは実装されていません。
OceanBaseデータベースでは、ローカル計画、リモート計画、および分散計画の3種類のテーブルルーティングがあります。ローカル計画とリモート計画はどちらも単一パーティションのルーティングです。ODPの役割は、リモート計画をできるだけ排除し、ルーティングをできるだけローカル計画に変更することです。テーブルルーティングタイプがリモート計画のSQLが多すぎる場合、そのODPのルーティングに問題がある可能性があります(oceanbase.GV$OB_SQL_AUDITビューのplan_typeフィールドを確認することで確認できます)。
非パーティションテーブルのルーティング
ODPには、PartitionとOBServer_addrのマッピングキャッシュが保存されています。PartitionはSQL Parserを通じてテーブル名を取得し、非パーティションテーブルはテーブル名からLocation Cacheでパーティション情報を取得します。パーティションテーブルへのアクセスで、ステートメントにパーティションキー値が提供されている場合は、そのパーティションキー値も取得し、テーブル名からLocation Cacheでパーティションメタデータを取得します。その後、パーティションキー値とパーティションメタデータを用いてパーティションIDを計算し、Partitionが存在するノードのIPアドレスを取得します。
以下の3つのケースがあります:
Location Cacheに存在しない場合、OBServerノードの
__all_virtual_proxy_schemaテーブルから取得します。Location Cacheに存在し利用可能な場合、直接使用します。
Location Cacheに存在するものの利用できない場合、Location Cacheから削除して再度取得します。
Location Cacheに関する詳細は、テナント内ルーティングを参照してください。
パーティションテーブルのルーティング
非パーティションテーブルと同様に、ODPにはPartitionとOBServer_addrのマッピングキャッシュが保存されており、PartitionはSQL Parser機能を通じてテーブル名を解析・取得します。非パーティションテーブルと比較して、パーティションテーブルにはパーティションID情報が追加されており、テーブル名とパーティションIDを用いてLocation CacheからPartitionが存在するOBServerのIPアドレスを取得します。
パーティションIDはSQLステートメントから取得され、その出所は通常where句の式やinsertステートメントのvalues値です。a = xxxを取得できることを保証する必要があります。ここで、aはパーティションキー、xxxは定数です。例:
obclient> CREATE TABLE t1(c1 int, c2 int) PARTITION BY hash(c1) partitions 5;
obclient> UPDATE t1 SET c2 = 3 WHERE c1 = 5;
ここからc1 = 5を抽出し、この情報を用いて影響を受けるパーティションIDを計算し、SQLを対応するパーティションが存在するOBServerノードに転送します。
ODPがパーティションIDを計算できない場合、正確なルートを取得することができません。obproxy.logログファイルで「calculate partition id」と検索して、計算が成功したかどうかを確認できます。例:
[root@ocp-deploy-obnorpm2-bfc89744b-qsfkz log]# grep "calculate partition id" obproxy.log
[2021-10-28 17:18:18.552825] DEBUG [PROXY] ob_mysql_route.cpp:577 [73979][Y0-7FB3C9D07A80] [lt=10] [dc=0] succ to calculate partition id(part_id_=1)
[2021-10-28 17:18:31.045191] INFO [PROXY] ob_mysql_route.cpp:575 [73979][Y0-7FB3C9D07A80] [lt=17] [dc=0] fail to calculate partition id, just use tenant server(tmp_ret=-4002)
パーティションテーブルに関する詳細は、パーティションの管理を参照してください。
ODPが依存するOceanBaseデータベースの内部テーブル
ルーティングの正確性は、ODP自体に関連するだけでなく、OceanBaseデータベースの内部テーブルから正しい情報を取得できるかどうかにも依存します。以下はODPが依存するOceanBaseデータベースの内部テーブルです:
__all_virtual_proxy_schema:パーティションとそのマシンの対応関係情報を保存するために使用され、Partitionの一部の関連情報も含まれます。__all_virtual_proxy_partition_info:パーティションテーブルに関連するパーティション情報を保存します。__all_virtual_proxy_partition:パーティション情報を保存します。__all_virtual_proxy_sub_partition:サブパーティション情報を保存します。