この章では、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:サブパーティション情報を保存します。