2 シャード・データベース・スキーマの設計
シャード・データベース・スキーマの概念について説明し、シャード・データベースのデータベース・スキーマを設計します。
- シャード・データベース・スキーマ設計の考慮点
データベース・スキーマの設計はシャード・データベースのパフォーマンスとスケーラビリティに大きく影響します。スキーマの設計が不適切な場合、データおよびワークロードがシャード間にバランスよく分散されず、マルチシャード操作の割合が大きくなります。 - シャード表
シャード表は、複数のデータベース間でより小さい管理しやすい断片にパーティション化された表であり、シャードと呼ばれます。 - シャード表ファミリ
シャード表ファミリは、同様にシャーディングされた一連の表です。 - パーティション、表領域およびチャンク
異なるシャードに存在する表領域にパーティションを作成することで、シャード間にパーティションを分散します。 - 重複表
シャード表に加えて、すべてのシャードで複製される表もSDBに格納できます。 - すべてのシャードに作成される表以外のオブジェクト
重複表に加えて、他のスキーマ・オブジェクト(ユーザー、ロール、ビュー、索引、シノニム、ファンクション、プロシージャ、パッケージなど)および非スキーマ・データベース・オブジェクト(表領域、表領域セット、ディレクトリ、コンテキストなど)をすべてのシャードに作成できます。 - シャード・データベースでのDDLの実行
シャード・データベースにスキーマを作成するには、シャード・カタログ・データベースでDDLコマンドを発行する必要があります。シャード・カタログ・データベースは、DDLを検証し、シャードで実行する前にそれらをローカルで実行します。 - シャード・データベースでのPL/SQLプロシージャの実行
構成内のすべてのシャードでDDL文を実行するのと同じ方法で、特定のOracle提供のPL/SQLプロシージャも実行できます。これらの特定のプロシージャ・コールは、シャードDDL文であるかのように動作します。この場合、それらはすべてのシャードに伝播され、カタログによって追跡され、新しいシャードが構成に追加されるたびに実行されます。 - シャード間の一意の順序番号の生成
Oracle Shardingを使用すると、主キー以外の列に対してシャード間でグローバルに一意の順序番号を生成できます。これはシャード・データベースで処理されます。 - シャード・データベース・ユーザーの作成
シャード・カタログ・データベースにのみ存在するローカル・ユーザーには、シャード・データベースにスキーマ・オブジェクトを作成するための権限がありません。シャード・データベース・スキーマ作成の最初のステップは、シャード・データベース・ユーザーの作成です。 - システム管理のシャード・データベースのスキーマの作成
シャード・データベースのスキーマ・ユーザー、表領域セット、シャード表および重複表を作成します。DDLがすべてのシャードに伝播されたことを確認し、シャードに接続されている状態で、ファスト・スタート・フェイルオーバーを使用した自動Data Guard Broker構成を検証します。 - ユーザー定義のSDBのスキーマの作成
SDBのスキーマ・ユーザー、表領域セット、シャード表および重複表を作成します。DDLがすべてのシャードに伝播されたことを確認し、シャードに接続されている状態で、ファスト・スタート・フェイルオーバーを使用した自動Data Guard Broker構成を検証します。 - コンポジットSDBのスキーマの作成
SDBのスキーマ・ユーザー、表領域セット、シャード表および重複表を作成します。DDLがすべてのシャードに伝播されたことを確認し、シャードに接続されている状態で、ファスト・スタート・フェイルオーバーを使用した自動Data Guard Broker構成を検証します。 - シャード・データベースでのプロキシ・ルーティングを使用した問合せおよびDML
シャーディングでは、シャーディング・キーを指定しない問合せのルーティングがサポートされます。これにより、データベース・アプリケーションが柔軟になり、問合せが実行されるシャードを指定することなく、表がシャーディングまたは複製されているシステムでSQL文(SELECT
およびDML
を含む)を実行できるようになります。
シャード・データベース・スキーマ設計の考慮点
データベース・スキーマの設計はシャード・データベースのパフォーマンスとスケーラビリティに大きく影響します。スキーマの設計が不適切な場合、データおよびワークロードがシャード間にバランスよく分散されず、マルチシャード操作の割合が大きくなります。
データ・モデルは、単一のルート表を持つ階層ツリー構造である必要があります。Oracle Shardingは任意のレベル数の階層をサポートします。
シャーディングの利点を活用するには、1つのシャードで実行されるデータベース・リクエストの数が最大になるように、シャード・データベースのスキーマを設計する必要があります。
シャード・データベース・スキーマは、次の特性を持つシャード表ファミリおよび重複表で構成されます。
シャード表ファミリ
- シャーディング・キーによって等価パーティション化された一連の表。
- 関連するデータは、常にまとめて格納および移動されます。
- 結合および整合性制約チェックはシャード内で実行されます。
- シャーディング方法およびキーは、アプリケーションの要件に基づいています。
- シャーディング・キーは、主キーに含まれている必要があります。
重複表
- すべてのシャードにレプリケートされる非シャード表。
- 通常、共通参照データが含まれます。
- 各シャードで読取りおよび更新できます。
シャード・データベース・スキーマの設計の計画
シャード・データーベースにデータを移入した後では、表をシャーディングするのか複製するのか、シャーディング・キーなど、スキーマの属性の多くは変更できません。したがって、シャード・データーベースをデプロイする前に次の点を慎重に考慮してください。
-
どの表をシャーディングするか?
-
どの表を複製するか?
-
どのシャード表をルート表にするか?
-
他の表をルート表にリンクするためにどの方法を使用するか?
-
どのシャーディング方法を使用するか?
-
どのシャーディング・キーを使用するか?
-
使用するスーパー・シャーディング・キー(シャーディング方法がコンポジットである場合)
親トピック: シャード・データベース・スキーマの設計
シャード表
シャード表は、複数のデータベース間でより小さい管理しやすい断片にパーティション化された表であり、シャードと呼ばれます。
Oracle ShardingはOracle Databaseのパーティション化機能に基づいて実装されています。Oracle Shardingは、シャード間の表パーティションの分散をサポートすることでパーティション化を拡張するため、事実上の分散パーティション化です。
パーティションはシャーディング・キーに基づいて表領域レベルでシャード間に分散されます。キーの例として顧客ID、アカウント番号、国IDなどがあります。
シャーディング・キーには次のデータ型がサポートされています。
-
NUMBER
-
INTEGER
-
SMALLINT
-
RAW
-
(N)VARCHAR
-
(N)VARCHAR2
-
(N)CHAR
-
DATE
-
TIMESTAMP
シャード表の各パーティションが個別の表領域に存在し、各表領域が特定のシャードと関連付けられます。シャーディング方法に応じて、関連付けは自動的に確立されるか、管理者によって定義されることができます。
シャード表のパーティションが複数のシャード内に存在する場合でも、アプリケーションにとってその表は、単一データベース内のパーティション表とまったく同じように表示され、動作します。アプリケーションによって発行されたSQL文はシャードを参照する必要はなく、シャードの数およびその構成に依存することもありません。
例2-1 シャード表
シャード間で行をパーティション化する方法は、表のパーティション化でよく目にするSQL構文によって指定します。たとえば、次のSQL文はシャーディング・キーcust_id
に基づいて、シャード間で表を水平にパーティション化したシャード表を作成します。
CREATE SHARDED TABLE customers
( cust_id NUMBER NOT NULL
, name VARCHAR2(50)
, address VARCHAR2(250)
, region VARCHAR2(20)
, class VARCHAR2(3)
, signup DATE
CONSTRAINT cust_pk PRIMARY KEY(cust_id)
)
PARTITION BY CONSISTENT HASH (cust_id)
PARTITIONS AUTO
TABLESPACE SET ts1
;
前述の表はコンシステント・ハッシュ(スケーラブルな分散システムで一般的に使用される特殊なタイプのハッシュ・パーティション化)によりパーティション化されます。この手法は、シャード間で表領域を自動的に分散するため、データおよびワークロードが均等に分散されます。シャード表に対するグローバル索引はサポートされていませんが、ローカル索引はサポートされています。
表領域セット
Oracle Shardingは、表領域セットと呼ばれる単位として表領域を作成および管理します。PARTITIONS AUTO
句は、パーティション数を自動的に判別することを指定します。このハッシュ・タイプによってシャード間のデータ移行でさらに柔軟性および効率性がもたらされ、これは弾力的な拡張性にとって重要です。
表領域はSDB内にデータを分散するための物理ユニットです。異なるシャードに存在する表領域にパーティションを自動的に作成することで、シャード間にパーティションを分散します。マルチシャード結合の数を最小にするために、関連する表の対応するパーティションは常に同じシャードに格納されます。シャード表の各パーティションが個別の表領域に格納されます。
ノート:
表領域セットでは、Oracle Managed Filesのみがサポートされます。
個々の表領域を表領域セット全体とは別個に削除または変更することはできません。
TABLESPACE SET
をユーザー定義のシャーディング方法とともに使用することはできません。
親トピック: シャード・データベース・スキーマの設計
シャード表ファミリ
シャード表ファミリは、同様にシャーディングされた一連の表です。
しばしば、データベースの表には親子関係があり、親表の主キーを参照する子表(外部キー)には参照制約があります。このような関係でリンクされている複数の表は、通常はツリーのような構造になり、各子が1つの親を持ちます。そのような一連の表は、表ファミリと呼ばれます。表ファミリ内の親を持たない表をルート表と呼びます。1つの表ファミリに存在できるルート表は1つのみです。
表ファミリのシャーディング方法
表ファミリのシャーディングを説明するために、Customers–Orders–LineItemsスキーマの例を取り上げます。このスキーマの表は次の例のようになります。3つの表に親子関係があり、Customersがルート表になります。
Customers表:
CustNo Name Address Location Class --------- ---------- -------------- --------- ------ 123 Brown 100 Main St us3 Gold 456 Jones 300 Pine Ave us1 Silver 999 Smith 453 Cherry St us2 Bronze
Orders表:
OrderNo CustNo OrderDate --------- -------- ----------- 4001 123 14-FEB-2013 4002 456 09-MAR-2013 4003 456 05-APR-2013 4004 123 27-MAY-2013 4005 999 01-SEP-2013
LineItems表:
LineNo OrderNo CustNo StockNo Quantity ------ ------- ------ ------- -------- 40011 4001 123 05683022 1 40012 4001 123 45423609 4 40013 4001 123 68584904 1 40021 4002 456 05683022 1 40022 4002 456 45423509 3 40022 4003 456 80345330 16 40041 4004 123 45423509 1 40042 4004 123 68584904 2 40051 4005 999 80345330 12
ルートであるCustomers表の顧客番号CustNo
に基づいて表をシャーディングできます。次の表の例には、顧客123に関連するデータが格納されたシャードが示されています。
Customers表:
CustNo Name Address Location Class --------- ---------- -------------- ---------- ------ 123 Brown 100 Main St us3 Gold
Orders表:
OrderNo CustNo OrderDate --------- -------- ----------- 4001 123 14-FEB-2013 4004 123 27-MAY-2013
LineItems表:
LineNo OrderNo CustNo StockNo Quantity ------ ------- ------ ------- -------- 40011 4001 123 05683022 1 40012 4001 123 45423609 4 40013 4001 123 68584904 1 40041 4004 123 45423509 1 40042 4004 123 68584904 2
CREATE TABLEを使用したシャード表ファミリの作成
シャード表ファミリは、参照パーティション化を使用し、表間の親子関係を指定して作成することをお薦めします。
次に、Customers–Orders–LineItemsスキーマに適切なCREATE TABLE
文を示します。最初の文でCustomersという表ファミリのルート表を作成します。
CREATE SHARDED TABLE Customers
( CustNo NUMBER NOT NULL
, Name VARCHAR2(50)
, Address VARCHAR2(250)
, CONSTRAINT RootPK PRIMARY KEY(CustNo)
)
PARTITION BY CONSISTENT HASH (CustNo)
PARTITIONS AUTO
TABLESPACE SET ts1
;
次の2つの文で、Customers表の子と孫であるOrders表とLineItems表を作成します。
CREATE SHARDED TABLE Orders
( OrderNo NUMBER NOT NULL
, CustNo NUMBER NOT NULL
, OrderDate DATE
, CONSTRAINT OrderPK PRIMARY KEY (CustNo, OrderNo)
, CONSTRAINT CustFK FOREIGN KEY (CustNo) REFERENCES Customers(CustNo)
)
PARTITION BY REFERENCE (CustFK)
;
CREATE SHARDED TABLE LineItems
( CustNo NUMBER NOT NULL
, LineNo NUMBER(2) NOT NULL
, OrderNo NUMBER(5) NOT NULL
, StockNo NUMBER(4)
, Quantity NUMBER(2)
, CONSTRAINT LinePK PRIMARY KEY (CustNo, OrderNo, LineNo)
, CONSTRAINT LineFK FOREIGN KEY (CustNo, OrderNo) REFERENCES Orders(CustNo, OrderNo)
)
PARTITION BY REFERENCE (LineFK)
;
前述の例の文では、ファミリ内のすべての表の対応するパーティションが同じ表領域セットTS1に格納されます。ただし、各表に個別の表領域セットを指定できます。
参照パーティション化の場合、ルート表のみにパーティション化スキームを指定するため構文が簡単です。また、ルート表に対して実行されるパーティション管理操作が自動的に子孫に伝播されます。たとえば、ルート表にパーティションを追加すると、すべての子孫に新しいパーティションが作成されます。
前述の例の文では、シャーディング・キーとして使用されているパーティション化列CustNo
は、3つの表のすべてに存在します。これは、参照パーティション化では一般に子表にキー列を複製することなく親表を使用して子表を等価パーティション化できるという事実と異なります。この理由は、子表をその親表にリンクするために使用される子表の外部キー制約には主キーを指定する必要があるので、参照パーティション化では親表に主キーが必要となるためです。ただし、シャード表の主キーは、シャーディング・キーと同じである必要があります。これにより、線形スケーラビリティの重要な要件である主キーのグローバルな一意性が、他のシャードと調整することなく維持されます。
要約すると、シャード・データベースで参照パーティション表を使用するには、次のルールに従う必要があります。
-
シャード表の主キーは、シャーディング・キーと同じであるか、最初の列がシャーディング・キーである複数の列である必要があります。他のシャードと調整することなく、主キーのグローバルな一意性を維持するためにこれが必要となります。
-
子表をその親表にリンクするための子表の外部キー制約には主キーを指定する必要があるため、参照パーティション化では親表に主キーが必要となります。たとえば、LineItems (子)表をOrders (親)表にリンクするには、Orders表に主キーが必要となります。この2番目のルールは、Orders表の主キーが
CustNo
値で始まることを意味します(これはOracle Shardingに固有ではない既存のパーティション化のルールです。)
場合によっては、参照パーティション化に必要な主キー制約と外部キー制約を作成することが不可能か望ましくないことがあります。そのような場合に表ファミリの親子関係を指定するには、すべての表が明示的に等価パーティション化され、各子表が親の名前を含むCREATE SHARDED TABLE
のPARENT
句を使用して作成される必要があります。次に、構文の例を示します。
CREATE SHARDED TABLE Customers
( CustNo NUMBER NOT NULL
, Name VARCHAR2(50)
, Address VARCHAR2(250)
, region VARCHAR2(20)
, class VARCHAR2(3)
, signup DATE
)
PARTITION BY CONSISTENT HASH (CustNo)
PARTITIONS AUTO
TABLESPACE SET ts1
;
CREATE SHARDED TABLE Orders
( OrderNo NUMBER
, CustNo NUMBER NOT NULL
, OrderDate DATE
)
PARENT Customers
PARTITION BY CONSISTENT HASH (CustNo)
PARTITIONS AUTO
TABLESPACE SET ts1
;
CREATE SHARDED TABLE LineItems
( LineNo NUMBER
, OrderNo NUMBER
, CustNo NUMBER NOT NULL
, StockNo NUMBER
, Quantity NUMBER
)
PARENT Customers
PARTITION BY CONSISTENT HASH (CustNo)
PARTITIONS AUTO
TABLESPACE SET ts1
;
すべてのCREATE SHARDED TABLE
文でパーティション化スキームが完全に指定されているため、任意の表を個別にサブパーティション化できます。ルート表のみにサブパーティションを指定でき、表ファミリのすべての表のサブパーティション化スキームが同じである参照パーティション化の場合、これは許可されません。
この方法は2レベルの表ファミリのみをサポートすることに注意してください。つまり、すべての子が同じ親を持つ必要があり、孫は存在できません。親表のパーティション化列がすべての子表に存在するかぎり、これは制限にはなりません。
チャンク
シャード間のデータ移行の単位はチャンクです。チャンクは、表ファミリのすべての表の対応するパーティションが格納される一連の表領域です。チャンクには、一連の関連表の各表の1つのパーティションが含まれます。これより、様々なシャード表の関連するデータが一緒に移動されることが保証されます。各シャード内のチャンクの数は、SDBを作成するときに指定します。
シャード・データベース内の複数の表ファミリ
ノート:
Oracle Database 19cでは、Oracle Shardingには複数の表ファミリのサポートが含まれています。この機能は、システム管理のシャード・データベースにのみ適用されます。コンポジットおよびユーザー定義のシャード・データベースでは、1つの表ファミリのみがサポートされます。シャード・データベースには複数の表ファミリを含めることができます。この場合、異なる表ファミリのデータはすべて同じチャンクに存在し、チャンクには同じハッシュ・キー範囲を共有する異なる表ファミリからのパーティションが含まれます。表ファミリ間の問合せは最小にする必要があり、シャーディング・コーディネータでのみ実行されるようにします。各表ファミリは、異なるグローバル・サービスに関連付けられています。異なる表ファミリからのアプリケーションにはそれぞれ独自の接続プールおよびサービスがあり、適切なシャードにルーティングするために独自のシャーディング・キーを使用します。
各表ファミリは、ルート表によって識別されます。異なる表ファミリの表は、互いに関連付けないでください。各表ファミリには独自のシャーディング・キー定義が必要ですが、子表に同じシャーディング・キー列があるという同じ制限が各表ファミリ内で当てはまります。つまり、異なる表ファミリからのすべての表は、コンシステント・ハッシュと同じ方法で同じ数のチャンクにシャーディングされ、各チャンクにはすべての表ファミリからのデータが含まれます。
次の例は、PARENT
句を使用して複数の表ファミリを作成する方法を示しています。
CREATE SHARDED TABLE Customers <=== Table Family #1
( CustId NUMBER NOT NULL
, Name VARCHAR2(50)
, Address VARCHAR2(250)
, region VARCHAR2(20)
, class VARCHAR2(3)
, signup DATE
)
PARTITION BY CONSISTENT HASH (CustId)
PARTITIONS AUTO
TABLESPACE SET ts1
;
CREATE SHARDED TABLE Orders
( OrderNo NUMBER
, CustId NUMBER
, OrderDate DATE
)
PARENT Customers
PARTITION BY CONSISTENT HASH (CustId)
PARTITIONS AUTO
TABLESPACE SET ts1
;
CREATE SHARDED TABLE LineItems
( LineNo NUMBER
, OrderNo NUMBER
, CustId NUMBER
, StockNo NUMBER
, Quantity NUMBER
)
)
PARENT Customers
PARTITION BY CONSISTENT HASH (CustId)
PARTITIONS AUTO
TABLESPACE SET ts1
;
CREATE SHARDED TABLE Products <=== Table Family #2
( ProdId NUMBER NOT NULL,
CONSTRAINT pk_products PRIMARY KEY (ProdId)
)
PARTITION BY CONSISTENT HASH (ProdId)
PARTITIONS AUTO
TABLESPACE SET ts_2
;
表領域セットが既存の表ファミリで使用されている場合、別の表ファミリにその表領域セットを使用しようとすると、ORA-3850がスローされます。
最初のルート表(つまり、最初の表ファミリ)を作成すると、すべての既存のグローバル・サービスがその表に自動的に関連付けられます。GDSCTLコマンドMODIFY SERVICE
を使用すると、表ファミリが追加で作成された後に表ファミリ・サービスの関連付けを変更できます。次に例を示します。
GDSCTL> MODIFY SERVICE –GDSPOOL shdpool –TABLE_FAMILY sales.customer -SERVICE sales
ノート:
表ファミリ間の結合は効率がよくないこともあるため、そのような結合が多数ある場合、またはパフォーマンスが重視されている場合は、複数の表ファミリではなく重複表を使用する必要があります。
関連項目:
『Oracle Database VLDBおよびパーティショニング・ガイド』
GDSCTLコマンド・リファレンスについては、『Oracle Database Global Data Services概要および管理ガイド』を参照してください
親トピック: シャード・データベース・スキーマの設計
パーティション、表領域およびチャンク
異なるシャードに存在する表領域にパーティションを作成することで、シャード間にパーティションを分散します。
シャード表の各パーティションが個別の表領域に格納され、表領域がSDBのデータ分散の単位になります。
シャード表ファミリで説明するように、マルチシャード結合の数を最小にするために、表ファミリのすべての表の対応するパーティションが常に同じシャードに格納されます。構文の例で表領域セットts1
がすべての表に使用されているように、1つの表ファミリの表が分散された表領域の同じセットに作成されるときに、これが保証されます。
ただし、1つの表ファミリの異なる表を異なる表領域のセットに作成することも可能です。たとえば、表領域セットts1
にCustomers表を作成し、表領域セットts2
にOrdersを作成できます。この場合、Customersのパーティション1が格納される表領域が常に、Ordersのパーティション1が格納される表領域と同じシャードに存在することが保証される必要があります。この機能をサポートするために、表ファミリのすべての表の対応するパーティションのセット(チャンクと呼ばれる)が作成されます。チャンクには表ファミリの各表の1つのパーティションが含まれます。
次の図に、Cutomers-Orders-LineItemsスキーマの表の対応するパーティションを含むチャンクを示します。
次の図のように、各シャードに複数のチャンクが含まれます。
シャード表に加えて、シャードには1つ以上の重複表も含めることができます。重複表は、シャード表に使用される表領域には格納できません。
親トピック: シャード・データベース・スキーマの設計
重複表
シャード表に加えて、すべてのシャードで複製される表もSDBに格納できます。
多くのアプリケーションの場合、単一のシャードで処理されるデータベース・リクエストの数は、すべてのシャードに読取り専用またはほぼ読取り専用の表を複製することによって最大化できます。この方法は、シャード表とともにアクセスされることがよくある比較的小さい表の場合は適切です。各シャードに同じ内容を含む表を重複表と呼びます。
SDBには、シャード間で水平にパーティション化されたシャード表、およびすべてのシャードにレプリケートされる重複表が含まれています。重複表には参照情報が含まれています(たとえば、各シャードで共通のStock Items表)。シャード表と重複表の組合せによって、シャーディング・キーに関連付けられているすべてのトランザクションを単一のシャードで処理できます。この技法によって、線形のスケーラビリティおよび障害の分離が可能になります。
重複表が必要な例として、シャード表ファミリで説明される表ファミリを取り上げます。データベース・スキーマにはProducts
表も含まれる可能性があり、この表には、この表ファミリに対して作成されたシャード内のすべての顧客が共有するデータが含まれますが、顧客番号でシャーディングすることはできません。注文処理中のマルチシャード問合せを回避するため、表全体をすべてのシャードに複製する必要があります。
シャード表(Customers、OrdersおよびLineItems)と重複表(Products)の違いを次の図に示します。
CREATE TABLEを使用した重複表の作成
重複表Productsは次の文を使用して作成できます。
CREATE DUPLICATED TABLE Products
( StockNo NUMBER PRIMARY KEY
, Description VARCHAR2(20)
, Price NUMBER(6,2))
;
重複表の更新とその内容の同期
Oracle Shardingは、マテリアライズド・ビュー・レプリケーションを使用して重複表の内容を同期します。各シャードの重複表がマテリアライズド・ビューとして表示されます。マテリアライズド・ビューのマスター表はシャード・カタログにあります。CREATE DUPLICATED TABLE
文によって、マスター表、マテリアライズド・ビュー、およびマテリアライズド・ビューのレプリケーションに必要なその他のオブジェクトが自動的に作成されます。
Oracle Database 12cリリース2では、重複表を更新するためにクライアントをシャード・カタログ・データベースに接続する必要があります。Oracle Database 18c以降では、シャードで重複した表を更新できます。更新は、まずdblinkを介してシャードからシャード・カタログのマスター表に伝播されます。その後、マテリアライズド・ビューのリフレッシュの結果として、更新が他のすべてのシャードに非同期的に伝播されます。
すべてのシャードのマテリアライズド・ビューが、構成可能な頻度で自動的にリフレッシュされます。すべての重複表のリフレッシュの頻度は、データベース初期化パラメータSHRD_DUPL_TABLE_REFRESH_RATE
によって制御されます。このパラメータのデフォルト値は、60秒です。
ノート:
シャードで実行されるトランザクションがシャード・カタログで削除された行を更新しようとすると、競合状態になる可能性があります。この場合、エラーが戻され、シャードのトランザクションがロールバックされます。
シャード上の重複表を更新する場合、次のユース・ケースはサポートされません。
-
LOBの更新またはdblinkでサポートされていないデータ型の更新
-
同じトランザクションによって挿入された行の更新または削除
親トピック: シャード・データベース・スキーマの設計
すべてのシャードに作成される表以外のオブジェクト
重複表に加えて、他のスキーマ・オブジェクト(ユーザー、ロール、ビュー、索引、シノニム、ファンクション、プロシージャ、パッケージなど)および非スキーマ・データベース・オブジェクト(表領域、表領域セット、ディレクトリ、コンテキストなど)をすべてのシャードに作成できます。
CREATE
文に追加のキーワード(SHARDED
またはDUPLICATED
)が必要となる表と異なり、他のオブジェクトは既存の構文を使用してすべてのシャードに作成します。唯一の要件は、SHARD DDL
セッション・プロパティを有効にする必要があることです。
すべてのシャードでの次のオブジェクトの自動作成は、このリリースではサポートされません。これらのオブジェクトは、個別のシャードに接続することによって作成できます。
-
クラスタ
-
制御ファイル
-
データベース・リンク
-
ディスク・グループ
-
エディション
-
フラッシュバック・アーカイブ
-
マテリアライズド・ゾーン・マップ
-
アウトライン
-
Pfile
-
プロファイル
-
リストア・ポイント
-
ロールバック・セグメント
-
サマリー
Oracle Database 18c以降では、マテリアライズド・ビューとビュー・ログがサポートされますが、次の制限事項があります。
-
シャード表に対して作成されたマテリアライズド・ビューは、カタログ・データベースでは空のままですが、シャード上の対応するマテリアライズド・ビューには個々のシャードのデータが含まれています。
-
シャード表のマテリアライズド・ビューでは、
REFRESH COMPLETE ON DEMAND USING TRUSTED CONSTRAINTS
オプションのみがサポートされます。
親トピック: シャード・データベース・スキーマの設計
シャード・データベースでのDDLの実行
DDLの伝播中にシャードが停止しているか、アクセスできない場合、カタログはそのシャードに適用できなかったDDLを追跡し、そのシャードがアクセス可能になったときにそれらを適用します。新しいシャードがシャード・データベースに追加された場合、クライアントがアクセスできるようになる前に、SDBで実行されたすべてのDDLがそのシャードに同じ順序で適用されます。
シャード・データベースでDDLを発行するには、次の2つの方法があります。
-
GDSCTL SQL
コマンドを使用します。この方法でDDLを発行した場合、そのDDLの実行がすべてのシャードで完了し、実行のステータスが返されるまで、
GDSCTL
は待機します。次に例を示しますGDSCTL> sql “create tablespace set tbsset”
-
GDS$CATALOG.sdbname
サービスを使用し、SQL*Plusを使用してシャード・カタログ・データベースに接続します。次に例を示しますSQL> create tablespace set tbsset;
シャード・カタログ・データベースに対してDDLを発行すると、ローカルでの実行が完了したときにステータスが返されますが、すべてのシャードへのDDLの伝播はバックグラウンドで非同期に行われます。
DDLの伝播の確認
シャードへのDDLの伝播のステータスを確認するには、GDSCTLのshow ddl
コマンドおよびconfig shard
コマンドを使用できます。シャード・カタログでSQL*Plusを使用してDDLを実行した場合、SQL*Plusではすべてのシャードの実行ステータスが返されないため、この確認は必須です。シャードでDDLが失敗した場合、その失敗が解決されて、GDSCTLのrecover shard
コマンドが実行されるまで、そのシャードに対するその後のすべてのDDLはブロックされます。これらのGDSCTLコマンドを実行するには、ユーザーにGSM_ADMIN権限がある必要があります。
ローカルまたはグローバルでのオブジェクトの作成
オブジェクトを作成するDDLがGDSCTLのsql
コマンドを使用して発行された場合、オブジェクトがすべてのシャードで作成されます。オブジェクトのマスター・コピーが、シャード・カタログ・データベースにも作成されます。すべてのシャードおよびカタログ・データベースに存在するオブジェクトは、SDBオブジェクトと呼ばれます。
SQL*Plusを使用してシャード・カタログに接続する場合、2つのタイプのオブジェクト(SDBオブジェクトよびローカル・オブジェクト)を作成できます。ローカル・オブジェクトは、シャード・カタログにのみ存在する従来のオブジェクトです。ローカル・オブジェクトは、管理のために使用したり、カタログ・データベースから発行されるマルチシャード問合せで(たとえば、レポートを生成および格納するために)使用したりできます。
SQL*Plusセッションで作成されるオブジェクトのタイプ(SDBまたはローカル)は、セッションでSHARD DDL
モードが有効にされているかどうかによって異なります。SDBユーザー(すべてのシャードおよびシャード・カタログ・データベースに存在するユーザー)の場合、このモードは、シャード・カタログ・データベースではデフォルトで有効になっています。セッションでSHARD DDL
が有効であるときに作成されたすべてのオブジェクトは、SDBオブジェクトです。ローカル・オブジェクトを作成するには、SDBユーザーは最初にalter session disable shard ddl
を実行する必要があります。SHARD DDL
が無効であるときに作成されたすべてのオブジェクトは、ローカル・オブジェクトです。セッションでSHARD DDL
を有効にするには、SDBユーザーはalter session enable shard ddl
を実行する必要があります。
SHARD DDL
セッション・パラメータの詳細は、ALTER SESSIONを参照してください。
DDLの実行例
次の例は、DDLを発行して実行ステータスを確認するステップ、およびエラーが発生した場合の対処方法を示しています。この例はSQL*Plusを使用してDDLを発行する場合の例を示していますが、GDSCTLのsql
コマンドを使用する場合も同じステータスの確認および修正のための対処を行います。
例2-2 シャード・カタログでのDDL実行エラー
この例では、ユーザーがCREATE USER
コマンドで入力ミスをしています。
SQL> alter session enable shard ddl;
Session altered.
SQL> CREATE USER example_user IDENTRIFIED BY out_standing1;
CREATE USER example_user IDENTRIFIED BY out_Standing1
*
ERROR at line 1:
ORA-00922: missing or invalid option
シャード・カタログでDDLの実行が失敗し、すべてのシャードでDDLが実行されなかったことがGDSCTLのshow ddl
コマンドに予想どおり表示されます。
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
その後、ユーザーが正しいスペリングでコマンドを実行し直します。同じセッションを使用しているため、alter session enable shard ddl
を再度実行する必要はありません。
SQL> CREATE USER example_user IDENTIFIED BY out_Standing1;
User created.
今度は、DDLがシャード・カタログ・データベースで正常に実行され、オンラインのシャードで失敗していないことがshow ddl
に示されます。
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user example_user identified by *****
ノート:
DDLの実行時に停止していたシャードの場合、DDLはそのシャードがアクセス可能になったときに自動的に適用されます。
例2-3 シャードで修正のための対処を実行することによって、シャードでのエラーをリカバリする
この例では、ユーザーはシステム管理のシャード表のための表領域セットを作成しようとします。ただし、1つのシャードのデータファイル・ディレクトリが書込み可能ではないため、DDLはカタログでは正常に実行されますが、そのシャードでは失敗します。
SQL> connect example_user/out_Standing1
Connected
SQL> create tablespace set tbsset;
Tablespace created.
ユーザーexample_userはSDBユーザーとして作成され、SHARD DDLがデフォルトで有効にされるため、alter session enable shard ddl
を実行する必要はありません。
GDSCTLのshow ddl
を使用してステータスを確認します。
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user example_user identified by *****
2 create tablespace set tbsset shard01
このコマンド出力は、シャードshard01でDDLが失敗したことを示しています。GDSCTLのconfig shard
コマンドを実行して、詳細情報を取得します。
GDSCTL> config shard -shard shard01
Conversion = ':'Name: shard01
Shard Group: dbs1
Status: Ok
State: Deployed
Region: east
Connection string: (DESCRIPTION=(ADDRESS=(HOST=shard01-host)(PORT=1521)(PROTOCOL=tcp))
(CONNECT_DATA=(SID=shard01)))
SCAN address:
ONS remote port: 0
Disk Threshold, ms: 20
CPU Threshold, %: 75
Version: 18.0.0.0
Failed DDL: create tablespace set tbsset
DDL Error: ORA-02585: create tablepsace set failure, one of its tablespaces not created
ORA-01119: error in creating database file \'/ade/b/3667445372/oracle/rdbms/dbs/
SHARD01/datafile/o1_mf_tbsset_%u_.dbf\'
ORA-27040: file create error, unable to create file
Linux-x86_64 Error: 13: Permission denied
Additional information: 1 \(ngsmoci_execute\)
Failed DDL id: 2
Availability: ONLINE
「Failed DDL:」で始まるテキストは問題を示しています。それを解決するには、ユーザーはシャード・データベースのホストにログインして、そのディレクトリを書込み可能にする必要があります。
ディレクトリの権限を表示します。
cd $ORACLE_HOME/rdbms/dbs
ls –l ../ | grep dbs
dr-xr-xr-x 4 oracle dba 102400 Jul 20 15:41 dbs/
ディレクトリを書込み可能に変更します。
chmod +w .
ls –l ../ | grep dbs
drwxrwxr-x 4 oracle dba 102400 Jul 20 15:41 dbs/
GDSCTL コンソールに戻って、recover shard
コマンドを発行します。
GDSCTL> recover shard -shard shard01
ステータスを再度確認します。
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user example_user identified by *****
2 create tablespace set tbsset
GDSCTL> config shard -shard shard01
Conversion = ':'Name: shard01
Shard Group: dbs1
Status: Ok
State: Deployed
Region: east
Connection string: (DESCRIPTION=(ADDRESS=(HOST=shard01-host)(PORT=1521)(PROTOCOL=tcp))
(CONNECT_DATA=(SID=shard01)))
SCAN address:
ONS remote port: 0
Disk Threshold, ms: 20
CPU Threshold, %: 75
Version: 18.0.0.0
Last Failed DDL:
DDL Error: ---
DDL id:
Availability: ONLINE
この出力に示されているように、失敗したDDLエラーが表示されなくなりました。
例2-4 他のすべてのシャードで修正のための対処を実行することによって、シャードでのエラーをリカバリする
この例では、ユーザーは別の表領域セットtbs_setを作成しようとしますが、同じ名前の既存のローカル表領域がすでに存在するため、シャードでDDLが失敗します。
シャード・カタログで次のコマンドを実行します。
SQL> create tablespace set tbs_set;
Tablespace created.
GDSCTLのshow ddl
コマンドを使用してステータスを確認します。
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user example_user identified by *****
2 create tablespace set tbsset
3 create tablespace set tbs_set shard01
GDSCTL> config shard -shard shard01
Conversion = ':'Name: shard01
……
Failed DDL: create tablespace set tbs_set
DDL Error: ORA-02585: create tablespace set failure, one of its tablespaces not created
ORA-01543: tablespace \'TBS_SET\' already exists \(ngsmoci_execute\)
この問題を解決するには、ローカル・データベース管理者としてshard01にログインし、表領域TBS_SETを削除して、GDSCTLのrecover shard -shard shard01
を実行します。ただし、この表領域を維持して、かわりに名前が競合している新しく作成した表領域セットを削除し、別の名前(tbsset2など)を持つ別の表領域セットを作成するとします。次の例では、シャード・カタログで実行する方法を示します。
SQL> drop tablespace set tbs_set;
SQL> create tablespace set tbs_set2;
GDSCTLを使用してステータスを確認します。
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user example_user identified by *****
2 create tablespace set tbsset
3 create tablespace set tbs_set shard01
4 drop tablespace set tbs_set
5 create tablespace set tbsset2
DDL 3がshard01で失敗したため、DDL 4および5はshard01で実行されなかったことがわかります。このシャードがシャード・カタログと整合性を持つようにするには、GDSCTLのrecover shard
コマンドを実行する必要があります。ただし、DDL 3は再び失敗し、実際には表領域セットtbs_setをもう作成するつもりがないため、このシャードでDDL 3を実行することは意味がありません。DDL 3をスキップするために、–ignore_first
オプションを指定してrecover shard
を実行します。
GDSCTL> recover shard -shard shard01 –ignore_first
GSM Errors: dbs1 shard01:ORA-00959: tablespace \'TBS_SET\' does not exist
(ngsmoci_execute)
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user sidney identified by *****
2 create tablespace set tbsset
3 create tablespace set tbs_set
4 drop tablespace set tbs_set shard01
5 create tablespace set tbsset2
DDL 3がスキップされたため、今度はDDL 3で失敗しません。ただし、次のDDL (4 - drop tablespace set tbs_set)が適用され、削除する表領域セットがシャードに存在しないため、エラーとなります。
–ignore_first
オプションは最初のDDLのみをスキップするため、recover shard
を再び実行してdrop
文もスキップする必要があります。
GDSCTL> recover shard -shard shard01 –ignore_first
GDSCTL> show ddl
id DDL Text Failed shards
-- -------- -------------
1 create user sidney identified by *****
2 create tablespace set tbsset
3 create tablespace set tbs_set
4 drop tablespace set tbs_set
5 create tablespace set tbsset2
失敗は表示されなくなり、すべてのDDLがシャードに正常に適用されました。
–ignore_first
オプションを指定してrecover shard
を実行した場合、失敗したDDLは増分デプロイメントで無視とマークされます。このため、新しいシャードがSDBに追加されたとき、DDL番号3および4はスキップされ、DDL番号1および5のみが適用されます。
Oracle ShardingのDDL構文拡張の詳細は、Oracle ShardingのDDL構文拡張を参照してください。
親トピック: シャード・データベース・スキーマの設計
シャード・データベースでのPL/SQLプロシージャの実行
構成内のすべてのシャードでDDL文を実行するのと同じ方法で、特定のOracle提供のPL/SQLプロシージャも実行できます。これらの特定のプロシージャ・コールは、シャードDDL文であるかのように動作します。この場合、それらはすべてのシャードに伝播され、カタログによって追跡され、新しいシャードが構成に追加されるたびに実行されます。
次のプロシージャはすべて、シャードDDL文であるかのように動作します。
- DBMS_FGAパッケージのプロシージャ
- DBMS_RLSパッケージのプロシージャ
- DBMS_STATSパッケージの次のプロシージャ:
- GATHER_INDEX_STATS
- GATHER_TABLE_STATS
- GATHER_SCHEMA_STATS
- GATHER_DATABASE_STATS
- GATHER_SYSTEM_STATS
- DBMS_GOLDENGATE_ADMパッケージの次のプロシージャ:
- ADD_AUTO_CDR
- ADD_AUTO_CDR_COLUMN_GROUP
- ADD_AUTO_CDR_DELTA_RES
- ALTER_AUTO_CDR
- ALTER_AUTO_CDR_COLUMN_GROUP
- PURGE_TOMBSTONES
- REMOVE_AUTO_CDR
- REMOVE_AUTO_CDR_COLUMN_GROUP
- REMOVE_AUTO_CDR_DELTA_RES
シャードDDL文と同じ方法でいずれかのプロシージャを実行するには、次のステップを実行します。
- gsm_pooladmin_roleを持つデータベース・ユーザーとしてSQL*Plusを使用して、シャード・カタログ・データベースに接続します。
alter session enable shard ddl
を使用してシャードDDLを有効にします。SYS.EXEC_SHARD_PLSQL
という名前のシャーディング固有のPL/SQLプロシージャを使用して、ターゲット・プロシージャを実行します。このプロシージャは、単一のCLOB引数を取ります。これは、完全修飾プロシージャ名とその引数を指定する文字列です。
EXEC_SHARD_PLSQL
を使用せずにターゲット・プロシージャを実行すると、そのプロシージャはカタログでのみ実行され、すべてのシャードに伝播されません。完全修飾名(たとえば、SYS.DBMS_RLS.ADD_POLICY
)を指定せずにプロシージャを実行すると、エラーが発生します。
たとえば、すべてのシャードでDBMS_RLS.ADD_POLICY
を実行するには、シャードDLLを有効にした後にSQL*Plusから次を実行します。
exec sys.exec_shard_plsql('sys.dbms_rls.add_policy(object_schema =>
''testuser1'',
object_name => ''DEPARTMENTS'',
policy_name => ''dept_vpd_pol'',
function_schema => ''testuser1'',
policy_function => ''authorized_emps'',
statement_types => ''INSERT, UPDATE, DELETE, SELECT, INDEX'',
update_check => TRUE)'
) ;
コール仕様自体はexec_shard_plsql
への文字列パラメータであるため、ターゲット・プロシージャ・コール仕様内に2つの一重引用符が必要なことに注意してください。
ターゲット・プロシージャがシャード・カタログ・データベースで正しく実行されると、現在デプロイされているすべてのシャードでの処理用にキューに入れられます。カタログでのターゲット・プロシージャ実行のエラーは、SQL*Plusセッションに戻されます。シャードでの実行時のエラーは、DDLの場合と同じ方法で追跡できます。
親トピック: シャード・データベース・スキーマの設計
シャード間の一意の順序番号の生成
Oracle Shardingを使用すると、主キー以外の列に対してシャード間でグローバルに一意の順序番号を生成できます。これはシャード・データベースで処理されます。
customer_idがシャーディング・キーの場合、顧客は大抵、主キー以外の列(order_idなど)に対して一意のIDを生成する必要があります。この場合、この機能を使用してシャード間で一意の順序番号を生成できますが、アプリケーション内の主キー以外の特定の列のグローバルな一意性を管理する必要はありません。
この機能は、新しいオブジェクトSHARDED SEQUENCE
でサポートされています。シャード順序はシャード・カタログに作成されますが、各シャード上にインスタンスがあります。各インスタンスは、他のシャードで使用される範囲とオーバーラップしない範囲に属する、単調に増加する番号を生成します。したがって、生成されたすべての番号はグローバルに一意になります。
たとえば、シャード順序を使用すると、顧客IDでシャーディングされた表に対して一意の順序番号を生成できます。顧客IDをキーとして使用してシャードへの接続を確立するアプリケーションでは、シャード順序のローカル・インスタンスを使用して、グローバルに一意の順序番号を生成できます。
シャード順序で生成された番号は、このシャードに挿入される新しい行のシャーディング・キーとしてすぐに使用できません。これは、キー値が別のシャードに属している場合に、挿入によってエラーが発生するためです。新しい行を挿入するには、まずアプリケーションでシャーディング・キーの値を生成し、それを使用して適切なシャードに接続する必要があります。シャーディング・キーの新しい値を生成する一般的な方法は、シャード・カタログで通常の(シャーディングされていない)順序を使用することです。
単一のシャーディング・キー・ジェネレータがボトルネックになっている場合、シャード順序をこの目的で使用できます。この場合、アプリケーションは(シャーディング・キーを指定せずにグローバル・サービスを使用して)ランダムなシャードに接続し、シャード順序から一意のキー値を取得してから、キー値を使用して適切なシャードに接続する必要があります。
この機能をサポートするために、次のCREATE
文の構文に示すように、新しいSEQUENCE
オブジェクト句、SHARD
およびNOSHARD
がSEQUENCE
オブジェクトのDDL構文に含まれます。
CREATE | ALTER SEQUENCE [ schema. ]sequence
[ { INCREMENT BY | START WITH } integer
| { MAXVALUE integer | NOMAXVALUE }
| { MINVALUE integer | NOMINVALUE }
| { CYCLE | NOCYCLE }
| { CACHE integer | NOCACHE }
| { ORDER | NOORDER }
| { SCALE {EXTEND | NOEXTEND} | NOSCALE}
| { SHARD {EXTEND | NOEXTEND} | NOSHARD}
]
NOSHARD
は、順序のデフォルトです。SHARD
句を指定すると、このプロパティは順序オブジェクトのディクショナリ表に登録され、DBA_SEQUENCES
、USER_SEQUENCES
およびALL_SEQUENCES
ビューを使用して表示されます。
SHARD
を指定すると、EXTEND
およびNOEXTEND
句によってシャード順序の動作が定義されます。EXTEND
を指定すると、生成された順序値はすべての長さ(x+y)になります。xは順序値の先頭に付加されるサイズ4のSHARD
オフセット(最大シャード数の幅に対応、つまり1000)の長さ、yは順序MAXVALUE
/MINVALUE
の最大桁数です。
SHARD
句のデフォルト設定はNOEXTEND
です。NOEXTEND
が設定されていると、生成される順序値の幅は最大でも順序内の数字の最大数(MAXVALUE
/MINVALUE
)です。この設定は、固定幅の列を移入するために順序が使用される、既存のアプリケーションとの統合に役立ちます。SHARD NOEXTEND
を指定した順序でNEXTVAL
を呼び出すと、生成された値に順序のMAXVALUE
/MINVALUE
よりも多くの桁数の表現が必要な場合は、ユーザー・エラーがスローされます。
SCALE
句もSHARD
句で指定されている場合、順序によって、グローバルに一意である複数のインスタンスおよびセッションに対してシャード内でスケーラブルな値が生成されます。EXTEND
をSHARD
キーワードとSCALE
キーワードの両方で指定する場合、生成された順序値はすべての長さ(x+y+z)になります。xは先頭に付加されるサイズ4のSHARD
オフセットの長さ、yはスケーラブルなオフセットの長さ(デフォルトは6)、zは順序MAXVALUE
/MINVALUE
の最大桁数です。
ノート:
SHARD
句を使用する場合は、順序にORDER
を指定しないでください。SHARD
を使用すると、グローバルに順序付けされていない値が生成されます。ORDER
が必要な場合は、各ノードでローカルに順序を作成します。
SHARD
キーワードは、CACHE
およびNOCACHE
モードの操作と組み合せて使用できます。
親トピック: シャード・データベース・スキーマの設計
シャード・データベース・ユーザーの作成
シャード・カタログ・データベースにのみ存在するローカル・ユーザーには、シャード・データベースにスキーマ・オブジェクトを作成するための権限がありません。シャード・データベース・スキーマ作成の最初のステップは、シャード・データベース・ユーザーの作成です。
SYSDBAとしてシャード・カタログ・データベースに接続して、SHARD DDL
を有効にし、CREATE USER
コマンドを実行してシャード・データベース・ユーザーを作成します。シャード・データベース・ユーザーがシャード・カタログ・データベースに接続すると、SHARD DDL
モードがデフォルトで有効になります。
ノート:
SHARD DDL
モードを有効にしている場合、ローカル・ユーザーは非スキーマのシャード・データベース・オブジェクト(表領域、ディレクトリ、コンテキストなど)を作成できます。ただし、スキーマ・オブジェクト(表、ビュー、索引、ファンクション、プロシージャなど)は作成できません。
シャード・オブジェクトは、ローカル・オブジェクトに対する依存性を持つことができません。たとえば、ローカル表にすべてのシャードを表示するビューを作成することはできません。
親トピック: シャード・データベース・スキーマの設計
システム管理のシャード・データベースのスキーマの作成
シャード・データベースのスキーマ・ユーザー、表領域セット、シャード表および重複表を作成します。DDLがすべてのシャードに伝播されたことを確認し、シャードに接続されている状態で、ファスト・スタート・フェイルオーバーを使用した自動Data Guard Broker構成を検証します。
関連項目:
GDSCTLコマンドの使用方法については、Oracle Database Global Data Services概要および管理ガイドを参照してください
親トピック: シャード・データベース・スキーマの設計
ユーザー定義のSDBのスキーマ作成
SDBのスキーマ・ユーザー、表領域セット、シャード表および重複表を作成します。DDLがすべてのシャードに伝播されたことを確認し、シャードに接続されている状態で、ファスト・スタート・フェイルオーバーを使用した自動Data Guard Broker構成を検証します。
関連項目:
GDSCTLコマンドの使用方法については、Oracle Database Global Data Services概要および管理ガイドを参照してください
親トピック: シャード・データベース・スキーマの設計
コンポジットSDBのスキーマ作成
SDBのスキーマ・ユーザー、表領域セット、シャード表および重複表を作成します。DDLがすべてのシャードに伝播されたことを確認し、シャードに接続されている状態で、ファスト・スタート・フェイルオーバーを使用した自動Data Guard Broker構成を検証します。
親トピック: シャード・データベース・スキーマの設計
シャード・データベースでのプロキシ・ルーティングを使用した問合せおよびDML
シャーディングでは、シャーディング・キーを指定しない問合せのルーティングがサポートされます。これにより、データベース・アプリケーションが柔軟になり、問合せが実行されるシャードを指定することなく、表がシャーディングまたは複製されているシステムでSQL文(SELECT
およびDML
を含む)を実行できるようになります。
次のトピックでは、プロキシ・ルーティングについてさらに詳しく説明します。
- シャード・データベースでのプロキシ・ルーティングについて
アプリケーションでは、複数のシャードからのデータを必要とする問合せや、シャーディング・キーを指定していない問合せを直接ルーティングできません。こうした問合せには、アプリケーションとシャードの間でリクエストをルーティングするためのプロキシが必要になります。 - マルチシャード問合せコーディネータ
Oracle Shardingのマルチシャード問合せコーディネータはコーディネータとも呼ばれるもので、シャード・カタログに含まれています。コーディネータには、シャード・トポロジのメタデータが含まれ、シャード・データベースの問合せ処理をサポートします。 - マルチシャード問合せコーディネータへの接続
Oracle Shardingマルチシャード問合せコーディネータ・データベース(シャード・カタログのコンポーネント)には、シャード・トポロジのメタデータが含まれ、シャード・データベースの問合せ処理をサポートします。 - プロキシ・ルーティングを使用した問合せおよびDML
プロキシ・ルーティングを使用すると、データを集計したり、複数のシャードに関するレポートを作成したりできます。また、データベース・アプリケーションが柔軟になり、表がシャーディング表または重複表であるシステムで、シャーディング・キーを指定することなくSQL文(SELECT
、DML
を含む)を実行できるようになります。 - 単一シャード問合せのためのプロキシ・ルーティング
単一シャード問合せは、1つのシャードでのみデータをスキャンする必要があり、他のシャードでデータを検索する必要がない問合せです。 - マルチシャード問合せのためのプロキシ・ルーティング
マルチシャード問合せは、複数のシャードでデータをスキャンする必要がある問合せであり、各シャードでの処理は他のシャードから独立しています。 - プロキシ・ルーティング用の実行計画
マルチシャード問合せでは、各シャードで別個の実行計画が生成されます。この実行計画はデータのサイズに応じて最適化され、シャードで使用可能なリソースが計算されます。 - サポートされる問合せ構成と問合せ形態の例
Oracle Shardingでは、単一シャード問合せとマルチシャード問合せの形態がサポートされていますが、いくつかの制限事項があります。 - Oracle Shardingのトランザクション処理
UPDATE
またはDELETE
DML文は、1つのシャードのみに影響するか、複数のシャードに影響する可能性があります。 - Oracle Shardingでサポートされる集計関数
Oracle Shardingでは、次の集計はプロキシ・ルーティングによってサポートされます。
親トピック: シャード・データベース・スキーマの設計
シャード・データベースでのプロキシ・ルーティングについて
アプリケーションでは、複数のシャードからのデータを必要とする問合せや、シャーディング・キーを指定していない問合せを直接ルーティングできません。こうした問合せには、アプリケーションとシャードの間でリクエストをルーティングするためのプロキシが必要になります。
プロキシ・ルーティングは次のシナリオに適しています。
-
接続中にアプリケーションがシャーディング・キーを渡すことができない
-
アプリケーションが複数のシャードに存在するシャード表のデータにアクセスする必要がある
-
レポート(販売データの集計など)に一般的に使用されるSQL問合せ
アプリケーションでワークロードを直接ルーティングとプロキシ・ルーティングに分離することをお薦めします。これらのワークロードのために、個別の接続プールを作成する必要があります。
プロキシ・ルーティングの動作
マルチシャード問合せとシャーディング・キーを指定しない問合せは、データをリクエストするアプリケーションのプロキシとして機能するマルチシャード問合せコーディネータを介してルーティングされます。マルチシャード問合せコーディネータ(またはコーディネータ)は、シャード・カタログまたはそのレプリカで実行します。
コーディネータは、シャード・データベース・トポロジのメタデータを使用し、シャード・データベースの問合せ処理をサポートします。SQLコンパイラは、関連するシャードを自動的に識別し、関与するすべてのシャード間での問合せの実行を調整します。コーディネータとのセッションが確立されると、変更を必要とせずにSQL問合せおよびDMLが実行されます。
コーディネータを使用したルーティングでは、接続中にシャーディング・キー値を渡すことなく、アプリケーションがSQL文を発行できます。コーディネータのSQLコンパイラは問合せを分析して問合せの断片にリライトし、それらが関与するシャードに送信されて実行されます。問合せは、関与するシャードでほとんどの問合せ処理が行われて、コーディネータによって集計されるようにリライトされます。
要するに、シャードはコーディネータによって実行された問合せの計算ノードとして動作します。計算がデータのあるシャードにプッシュされるため、シャードとコーディネータの間のデータの移動が減少します。この仕組みによって、コーディネータの処理負荷ができるだけ多くのシャードに移動するため、リソースを効率的に使用できるようになります。
プロキシ・ルーティングの回復力
コーディネータの障害は、コーディネータを介してルーティングされるマルチシャード問合せおよび単一シャード問合せに影響します。問合せの実行中の障害のシナリオ、およびプロキシ・ルーティングの予期される動作を次に示します。
-
関与するシャードが停止している場合、コーディネータは同じデータを使用してその問合せを別のシャードに送信します。
-
関与するシャードに対して問合せを実行しているときに障害が発生した場合、ユーザーはエラーを受け取ります。
マルチシャード問合せコーディネータ
Oracle Shardingのマルチシャード問合せコーディネータはコーディネータとも呼ばれるもので、シャード・カタログに含まれています。コーディネータには、シャード・トポロジのメタデータが含まれ、シャード・データベースの問合せ処理をサポートします。
マルチシャード問合せとシャーディング・キーを指定しない問合せは、データをリクエストするアプリケーションのプロキシとして機能するマルチシャード問合せコーディネータを介してルーティングされます。マルチシャード問合せコーディネータは、シャード・カタログまたはそのレプリカで実行します。コーディネータによるプロキシ・ルーティングが問合せに必要な場合、シャード・カタログ・データベースはコーディネータ・データベースの役割を果たします。
コーディネータは、シャード・データベース・トポロジのメタデータを使用し、シャード・データベースの問合せ処理をサポートします。SQLコンパイラは、関連するシャードを自動的に識別し、関与するすべてのシャード間での問合せの実行を調整します。コーディネータとのセッションが確立されると、変更を必要とせずにSQL問合せおよびDMLが実行されます。
要するに、シャードはコーディネータによって実行された問合せの計算ノードとして動作します。計算がデータのあるシャードにプッシュされるため、シャードとコーディネータの間のデータの移動が減少します。この仕組みによって、コーディネータの処理負荷ができるだけ多くのシャードに移動するため、リソースを効率的に使用できるようになります。
マルチシャード問合せコーディネータへの接続
Oracle Shardingマルチシャード問合せコーディネータ・データベース(シャード・カタログのコンポーネント)には、シャード・トポロジのメタデータが含まれており、シャード・データベースの問合せ処理をサポートします。
プロキシ・ルーティングを使用した問合せおよびDML
プロキシ・ルーティングを使用すると、データを集計したり、複数のシャードに関するレポートを作成したりできます。また、データベース・アプリケーションが柔軟になり、表がシャーディング表または重複表であるシステムで、シャーディング・キーを指定することなくSQL文(SELECT
、DML
を含む)を実行できるようになります。
シャード・データベースのプロキシ・ルーティングは、アプリケーションが関連するシャードを指定することなく、シャード表および重複表のデータにアクセスする通常のSQL問合せを実行するための透過的なメカニズムを提供します。SQLコンパイラは、関連するシャードを自動的に識別し、関与するすべてのシャード間での問合せの実行を調整します。コーディネータとシャードの間の通信のために、データベース・リンクが使用されます。
大まかに言うと、コーディネータは各受信問合せQを2つの問合せ(CQおよびSQ)で構成される分配形式にリライトします。ここで、SQ (シャード問合せ)は関与する各シャードで実行されるQの部分であり、CQ (コーディネータ問合せ)はコーディネータ・シャードで実行されるQの部分です。
Q => CQ ( Shard_Iterator( SQ ) )
次の例では、集計問合せQ1をQ1'にリライトしています。
Q1 : SELECT COUNT(*) FROM customers
Q1’: SELECT SUM(sc) FROM (Shard_Iterator(SELECT COUNT(*) sc FROM s1 (i) ))
この処理には2つの主要な要素があります。
-
関連するシャードが識別されます。
-
問合せが分散形式にリライトされ、関連するシャードで繰り返されます。
コーディネータ・データベースでの問合せのコンパイル中に、問合せコンパイラはシャーディング・キーに対する述語を分析し、関与するシャード(つまり、問合せで参照されるシャード表の行があるシャード)を識別するために使用できる述語を抽出します。残りのシャードは除外されたシャードと呼ばれます。
関与するシャードが1つのみ識別された場合は、問合せ全体がそのシャードにルーティングされて実行されます。これは単一シャード問合せと呼ばれます。
関与する複数のシャードがある場合、その問合せはマルチシャード問合せと呼ばれ、リライトされます。リライト処理では、問合せによって計算される式および問合せの形態が考慮されます。
ノート:
シャーディング・キーを指定しないデータ集計またはSQL実行の場合、キーベースの直接のルーティングと比較すると、パフォーマンス・レベルの低下を受け入れる必要があります。単一シャード問合せのためのプロキシ・ルーティング
単一シャード問合せは、1つのシャードでのみデータをスキャンする必要があり、他のシャードでデータを検索する必要がない問合せです。
単一シャード問合せは、特定のシャードに接続してそのシャードに問合せを発行するクライアントに似ています。このシナリオでは、問合せ全体が関与する単一のシャードで実行され、コーディネータは処理された行をクライアントに返すだけです。コーディネータの計画は、リモート・マップ・カーソルに似ています。
たとえば、次の問合せは、顧客123のデータが1つのシャードのみにあるため、そのシャードにすべてマップされます。
SELECT count(*) FROM customers c, orders o WHERE c.custno = o.custno and c.custno = 123;
この問合せには、問合せのコンパイル時(リテラル)または問合せ開始時(バインド)に判明する1つのシャードにのみマップするシャード・キーの条件が含まれています。問合せは該当するシャードですべて実行されます。
単一シャード問合せでは次のものがサポートされます。
-
等価およびINリスト(
Area = 'West'
など) -
リテラル、バインド、またはリテラルとバインドの式を含む次のような条件
Area = :bind Area = CASE :bind <10 THEN ‘West’ ELSE ‘East’ END
-
SELECT
、UPDATE
、DELETE
、INSERT
、FOR UPDATE
およびMERGE
。UPSERT
はサポートされていません。
マルチシャード問合せのためのプロキシ・ルーティング
マルチシャード問合せは、複数のシャードでデータをスキャンする必要がある問合せであり、各シャードでの処理は他のシャードから独立しています。
マルチシャード問合せは、複数のシャードにマップされ、結果をクライアントに送信する前に、コーディネータが処理する必要がある場合があります。たとえば、次の問合せは各顧客によって発注されたオーダー数を取得します。
SELECT count(*), c.custno FROM customers c, orders o WHERE c.custno = o.custno
GROUP BY c.custno;
この問合せは、コーディネータによって次のように変換されます。
SELECT sum(count_col), custno FROM (SELECT count(*) count_col, c.custno
FROM customers c, orders o
WHERE c.custno = o.custno GROUP BY c.custno) GROUP BY custno;
インライン問合せブロックは、リモート・マップ問合せブロックのように各シャードにマップされます。コーディネータは、すべてのシャードからの結果セットに対して、さらなる集計およびGROUP BY
を実行します。各シャードでの実行の単位はインライン問合せブロックです。
マルチシャード問合せとグローバルな読取り一貫性
マルチシャード問合せでは、すべてのシャードで最も大きい共通SCNで問合せを発行することによって、グローバルな読込み一貫性(CR)を維持する必要があります。一貫性レベルを設定する方法の詳細は、マルチシャード問合せでの一貫性レベルの指定を参照してください。
マルチシャード問合せでのヒントの受け渡し
コーディネータに対する元の問合せで指定したヒントは、シャードに伝播されます。
マルチシャード問合せでの実行速度低下のトレースとトラブルシューティング
クエリー・リライトおよびシャード・プルーニングをトレースするには、コーディネータに対してトレース・イベントshard_sql
を設定します。観測される一般的なパフォーマンス問題の1つは、シャーディングの一定の制限により、GROUP BYがシャードにプッシュされない場合です。考えられるすべての操作がシャードにプッシュされ、シャードからの結果を統合するためのコーディネータでの処理が最低限であるかどうかを確認します。
- マルチシャードDMLのサポートの制限事項
次のDML機能は、Oracle ShardingのマルチシャードDMLではサポートされません。 - マルチシャード問合せでの一貫性レベルの指定
シャード間でマルチシャード問合せを実行するときに、初期化パラメータMULTISHARD_QUERY_DATA_CONSISTENCYを使用して様々な一貫性レベルを設定できます。
マルチシャードDMLのサポートの制限事項
次のDML機能は、Oracle ShardingのマルチシャードDMLではサポートされません。
- パラレルDML パラレルDMLはマルチシャードDMLではサポートされません。マルチシャードDMLでは、DMLは常に一度に1つのシャードに対して(シリアルに)実行されます。
- エラー・ロギング DMLの
ERROR LOG
句は、マルチシャードDMLではサポートされません。この場合、ユーザー・エラーが発生します。 - 配列DML 配列DMLはマルチシャードDMLではサポートされません。この場合、ORA-2681が発生します。
- RETURNING句
RETURNING INTO
句は通常の分散DMLでサポートされないため、Oracle Shardingでサポートされません。マルチシャードDMLでRETURNING INTO
句の使用を試みると、ORA-22816が発生します。 - MERGEおよびUPSERT
MERGE
文はOracle Shardingで部分的にサポートされます。つまり、単一のシャードのみに影響するMERGE
文はサポートされます。MERGE
文で複数のシャードの変更が必要となる場合は、ORAエラーが発生します。 - 複数表へのINSERT 複数表への挿入はデータベース・リンクでサポートされないため、Oracle Shardingでサポートされません。
- 更新可能な結合ビュー 更新可能な結合ビューでシャード表がシャーディング・キーで結合されている場合、ORA-1779がスローされます。このエラーの理由は、シャード表に定義されている主キーが内部列
SYS_HASHVAL
+ シャーディング・キーの組合せであるため、更新可能な結合ビューにSYS_HASHVAL
を指定できないからです。この制限により、キー保存表を設定できないため、ORA-1779が発生します。 - トリガー
親トピック: マルチシャード問合せのためのプロキシ・ルーティング
マルチシャード問合せでの一貫性レベルの指定
シャード間でマルチシャード問合せを実行するときに、初期化パラメータMULTISHARD_QUERY_DATA_CONSISTENCYを使用して様々な一貫性レベルを設定できます。
マルチシャード問合せでは、様々な一貫性レベルを指定できます。たとえば、一部の問合せでシャード間のSCN同期のコストを回避する必要がある場合は、それらのシャードをグローバルに分散できます。別のユース・ケースとして、レプリケーション用のスタンバイを使用している場合は、プライマリとそのスタンバイから結果がフェッチされる可能性があるため、マルチシャード問合せで少し古いデータが許容されます。
デフォルトのモードは厳密な一貫性であり、すべてのシャード間でSCN同期が実行されます。他のモードでは、SCN同期はスキップされます。delayed_standby_allowedレベルでは、ロード・バランシングなどの要因に応じてスタンバイからもデータをフェッチでき、古いデータを含めることができます。
このパラメータは、システム・レベルまたはセッション・レベルで設定できます。
関連項目:
MULTISHARD_QUERY_DATA_CONSISTENCYの使用方法の詳細は、Oracle Databaseリファレンスを参照してください。
親トピック: マルチシャード問合せのためのプロキシ・ルーティング
プロキシ・ルーティング用の実行計画
マルチシャード問合せでは、各シャードで別個の実行計画が生成されます。この実行計画はデータのサイズに応じて最適化され、シャードで使用可能なリソースが計算されます。
SQLフラグメントの実行計画を参照するために、個々のシャードに接続する必要はありません。dbms_xplan.display_cursor()
で提供されるインタフェースは、シャードで実行されたSQLセグメントの計画をコーディネータに表示します。また、[V/X]$SHARD_SQL
は、マルチシャード問合せのシャードSQLフラグメントをターゲットのシャード・データベースに一意にマップします。
dbms_xplan.display_cursor()
のSQLセグメント・インタフェース
2つのインタフェースを使用して、シャードで実行されたSQLセグメントの計画を表示できます。これらのインタフェースは、引数としてシャードIDを取り、指定されたシャードの計画を表示します。ALL_SHARDS
形式では、すべてのシャードの計画が表示されます。
シャードのすべての計画を出力するには、次に示すようにformat
値ALL_SHARDS
を使用します。
select * from table(dbms_xplan.display_cursor(sql_id=>:sqlid,
cursor_child_no=>:childno,
format=>'BASIC +ALL_SHARDS‘,
shard_ids=>shard_ids))
シャードの計画を選択して出力するには、display_cursor()
関数内でシャードIDを渡します。複数のシャードの計画を出力する場合は、次に示すようにshard_ids
パラメータでシャードIDを含む数値の配列を渡します。
select * from table(dbms_xplan.display_cursor(sql_id=>:sqlid,
cursor_child_no=>:childno,
format=>'BASIC',
shard_ids=>ids))
1つのシャードの計画を返すには、次に示すようにshard_id
パラメータにシャードIDを直接渡します。
select * from table(dbms_xplan.display_cursor(sql_id=>:sqlid,
cursor_child_no=>:childno,
format=>'BASIC',
shard_id=>1))
V$SQL_SHARD
V$SQL_SHARD
は、マルチシャード問合せのシャードSQLフラグメントをターゲットのシャード・データベースに一意にマップします。このビューは、特定のマルチシャード問合せのシャードSQLフラグメントごとにアクセスされたシャードのリストがシャード・コーディネータ・データベースに格納されている場合にのみ関連します。マルチシャード問合せを実行するたびに、異なるシャードのセットに対してシャードSQLフラグメントを実行できるため、実行のたびにシャードIDが更新されます。このビューには、各リモート・ノードのシャードSQLフラグメントのSQL IDと、シャードSQLフラグメントが実行されたシャードIDが保持されています。
Name Null? Type
----------------------------------------- -------- ----------------------------
SQL_ID VARCHAR2(13)
CHILD_NUMBER NUMBER
NODE_ID NUMBER
SHARD_SQL_ID VARCHAR2(13)
SHARD_ID NUMBER
SHARD_CHILD_NUMBER NUMBER
-
SQL ID - コーディネータ上のマルチシャード問合せのSQL ID
-
CHILD_NUMBER - コーディネータ上のマルチシャード問合せのカーソル子番号
-
NODE - マルチシャード問合せのシャードSQLフラグメントのリモート・ノードのID
-
SHARD_SQL_ID - 指定されたリモート・ノードIDに対するシャードSQLフラグメントのSQL ID
-
SHARD_ID - シャードSQLフラグメントが実行されたシャードのID
-
SHARD_CHILD_NUMBER - シャードに対するシャードSQLフラグメントのカーソル子番号(デフォルトは0)
シャード・データベースに対するマルチシャード問合せと実行計画の例を次に示します。
SQL> select count(*) from departments a where exists (select distinct department_id
from departments b where b.department_id=60);
------------------------------------------------
| Id | Operation | Name |
------------------------------------------------
| 0 | SELECT STATEMENT | |
| 1 | SORT AGGREGATE | |
| 2 | FILTER | |
| 3 | VIEW | VW_SHARD_377C5901 |
| 4 | SHARD ITERATOR | |
| 5 | REMOTE | |
| 6 | VIEW | VW_SHARD_EEC581E4 |
| 7 | SHARD ITERATOR | |
| 8 | REMOTE | |
------------------------------------------------
V$SQL_SHARD
ビューに対するSQL_IDの問合せ。
SQL> Select * from v$sql_shard where SQL_ID = ‘1m024z033271u’;
SQL_ID NODE_ID SHARD_SQL_ID SHARD_ID
------------- ------- -------------- --------
1m024z033271u 5 5z386yz9suujt 1
1m024z033271u 5 5z386yz9suujt 11
1m024z033271u 5 5z386yz9suujt 21
1m024z033271u 8 8f50ctj1a2tbs 11
サポートされる問合せ構成と問合せ形態の例
Oracle Shardingでは、単一シャード問合せとマルチシャード問合せの形態がサポートされていますが、いくつかの制限事項があります。
Oracle Shardingでの問合せコンストラクトに関する制限事項は、次のとおりです。
-
CONNECT BYを使用する問合せ
CONNECT BY
を使用する問合せはサポートされません。 -
MODEL句
MODEL
句はサポートされていません。 -
WHERE句のユーザー定義のPL/SQL マルチシャード問合せでは、ユーザー定義のPL/SQLは
SELECT
句でのみ使用できます。WHERE
句で指定された場合は、エラーがスローされます。 -
XLATEおよびXML問合せタイプ XLATEおよびXML問合せタイプの列はサポートされません。
-
オブジェクト型 オブジェクト型を
SELECT
リスト、WHERE
句などに含めることはできますが、オブジェクト型のカスタム・コンストラクタおよびメンバー関数をWHERE
句に含めることはできません。さらに、重複表の場合、NOT FINAL型(つまり
NOT FINAL
キーワードを指定して作成されたオブジェクト型)は、列のデータ型として使用できません。シャード表の場合、NOT FINAL型を列のデータ型として使用できますが、キーワードNOT SUBSTITUTABLE AT ALL LEVELS
を指定して列を作成する必要があります。
ノート:
重複表のみに関連する問合せは、コーディネータで実行されます。次のトピックでは、Oracle Shardingでサポートされる問合せ形態の例をいくつか示します。
- シャード表のみに対する問合せ
単一表の問合せの場合、問合せにはシャードを限定するシャーディング・キーに対する等価フィルタを指定できます。結合問合せの場合は、すべての表がシャーディング・キーに対する等価フィルタを使用して結合される必要があります。 - シャード表と重複表が関係する問合せ
シャード表と重複表が関係する問合せは、シャーディング・キーに対する述語に応じて、単一シャード問合せまたはマルチシャード問合せになります。唯一の違いは、問合せに非シャード表が含まれていることです。
シャード表のみに対する問合せ
単一表の問合せの場合、問合せにはシャードを限定するシャーディング・キーに対する等価フィルタを指定できます。結合問合せの場合は、すべての表がシャーディング・キーに対する等価フィルタを使用して結合される必要があります。
次の例は、シャード表のみが関与する問合せを示しています。
例2-5 内部結合
SELECT … FROM s1 INNER JOIN s2 ON s1.sk=s2.sk
WHERE any_filter(s1) AND any_filter(s2)
例2-6 左外部結合
SELECT … FROM s1 LEFT OUTER JOIN s2 ON s1.sk=s2.sk
例2-7 右側外部結合
SELECT … FROM s1 RIGHT OUTER JOIN s2 ON s1.sk=s2.sk
例2-8 完全外部結合
SELECT … FROM s1 FULL OUTER JOIN s2 ON s1.sk=s2.sk
WHERE any_filter(s1) AND any_filter(s2)
親トピック: サポートされる問合せ構成と問合せ形態の例
シャード表および重複表の両方が関係する問合せ
シャード表と重複表が関係する問合せは、シャーディング・キーに対する述語に応じて、単一シャード問合せまたはマルチシャード問合せになります。唯一の違いは、問合せに非シャード表が含まれていることです。
ノート:
シャード表と重複表の結合では、任意の列で、任意の比較演算子(= < > <= >=)または任意の結合式を使用できます。例2-9 内部結合
SELECT … FROM s1 INNER JOIN r1 ON any_join_condition(s1,r1)
WHERE any_filter(s1) AND any_filter(r1)
例2-10 左外部結合または右外部結合
この場合、シャード表はLEFT OUTER JOIN
の最初の表です。
SELECT … FROM s1 LEFT OUTER JOIN r1 ON any_join_condition(s1,r1)
WHERE any_filter(s1) AND any_filter(r1)
SELECT … FROM r1 LEFT OUTER JOIN s1 ON any_join_condition(s1,s2)
AND any_filter(r1) AND filter_one_shard(s1)
この場合、シャード表はRIGHT OUTER JOIN
の2番目の表です。
SELECT … FROM r1 RIGHT OUTER JOIN s1 ON any_join_condition(s1,r1)
WHERE any_filter(s1) AND any_filter(r1)
SELECT … FROM s1 RIGHT OUTER JOIN r1 ON any_join_condition(s1,s2)
AND filter_one_shard(s1) AND any_filter(r1)
場合によっては、重複表がLEFT OUTER JOIN
の最初の表であるか、シャード表が最初の表でシャーディング・キーに対するフィルタ述語に基づいて単一のシャードにマップされます。
SELECT … FROM r1 LEFT OUTER JOIN s1 ON any_join_condition(s1,s2)
AND any_filter(r1) AND any_filter(s1)
場合によっては、重複表がRIGHT OUTER JOIN
の2番目の表であるか、シャード表が2番目の表でシャーディング・キーに対するフィルタ述語に基づいて単一のシャードにマップされます。
SELECT … FROM s1 RIGHT OUTER JOIN r1 ON any_join_condition(s1,s2)
AND any_filter (s1) AND any_filter(r1)
例2-11 完全外部結合
SELECT … FROM s1 FULL OUTER JOIN r1 ON s1.sk=s2.sk
WHERE any_filter(s1) AND any_filter(s2)
この場合、シャード表で複数のシャードへのアクセスが必要となります。
SELECT … FROM s1 FULL OUTER JOIN r1 ON s1.non_sk=s2.non_sk
WHERE any_filter(s1) AND any_filter(s2)
例2-12 セミ結合(EXISTS
)
SELECT … FROM s1 EXISTS
(SELECT 1 FROM r1 WHERE r1.anykey=s1.anykey)
SELECT … FROM r1 EXISTS
(SELECT 1 FROM s1 WHERE r1.anykey=s1.anykey and filter_one_shard(s1))
この場合、シャード表は複数シャードの関与を必要とする副問合せにあります。
SELECT … FROM r1 EXISTS
(SELECT 1 FROM s1 WHERE r1.anykey=s1.anykey)
例2-13 アンチ結合(NOT EXISTS
)
SELECT … FROM s1 NOT EXISTS
(SELECT 1 FROM r1 WHERE r1.anykey=s1.anykey)
この場合、シャード表は副問合せにあります。
SELECT … FROM r1 NOT EXISTS
(SELECT 1 FROM s1 WHERE r1.anykey=s1.anykey
親トピック: サポートされる問合せ構成と問合せ形態の例
Oracle Shardingのトランザクション処理
UPDATE
またはDELETE
DML文は、1つのシャードのみに影響するか、複数のシャードに影響する可能性があります。
EMPLOYEES
表に影響するDML文を次に示します。
UPDATE employees SET salary = salary *1.1;
前述のUPDATE
文は、WHERE
句がないため、EMPLOYEES
表のすべての行に影響します。
このUPDATE
文をすべてのシャードで実行するために、シャード・コーディネータがすべてのプライマリ・データベースに対して反復処理を行い、UPDATE
文のリモート実行を呼び出します。コーディネータは分散トランザクションを開始し、2フェーズ・コミットを実行して分散トランザクションの一貫性を保証します。インダウト・トランザクションの場合は、手動でリカバリする必要があります。