2 シャード・データベース・スキーマの設計

シャーディングの利点を活用するには、1つのシャードで実行されるデータベース・リクエストの数が最大になるように、シャード・データベースのスキーマを設計する必要があります。

次のトピックでは、この目的で使用されるオブジェクトについて説明します。

シャード表

シャード表は、複数のデータベース間でより小さい管理しやすい断片にパーティション化された表であり、シャードと呼ばれます。

Oracle ShardingはOracle Databaseのパーティション化機能に基づいて実装されています。Oracle Shardingは、シャード間の表パーティションの分散をサポートすることでパーティション化を拡張するため、事実上の分散パーティション化です。

パーティションはシャーディング・キーに基づいて表領域レベルでシャード間に分散されます。キーの例として顧客ID、アカウント番号、国IDなどがあります。シャーディング・キーには次のデータ型がサポートされています。

  • NUMBER

  • INTEGER

  • SMALLINT

  • RAW

  • (N)VARCHAR

  • (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つのパーティションが含まれます。これより、様々なシャード表の関連するデータが一緒に移動されることが保証されます。各シャード内のチャンクの数は、SDBを作成するときに指定します。

シャード表ファミリ

シャード表ファミリは、同様にシャーディングされた一連の表です。

しばしば、データベースの表には親子関係があり、親表の主キーを参照する子表(外部キー)には参照制約があります。このような関係でリンクされている複数の表は、通常はツリーのような構造になり、各子が1つの親を持ちます。そのような一連の表は、表ファミリと呼ばれます。表ファミリ内の親を持たない表をルート表と呼びます。1つの表ファミリに存在できるルート表は1つのみです。

ノート:

Oracle Database 12cリリース2では、SDBで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 TABLEPARENT句を使用して作成される必要があります。次に、構文の例を示します。

 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レベルの表ファミリのみをサポートすることに注意してください。つまり、すべての子が同じ親を持つ必要があり、孫は存在できません。親表のパーティション化列がすべての子表に存在するかぎり、これは制限にはなりません。

ノート:

Oracle Database 12cリリース2では、SDBで1つの表ファミリのみがサポートされます。

重複表

シャード表に加えて、すべてのシャードで複製される表もSDBに格納できます。

多くのアプリケーションの場合、単一のシャードで処理されるデータベース・リクエストの数は、すべてのシャードに読取り専用またはほぼ読取り専用の表を複製することによって最大化できます。この方法は、シャード表とともにアクセスされることがよくある比較的小さい表の場合は適切です。各シャードに同じ内容を含む表を重複表と呼びます。

SDBには、シャード間で水平にパーティション化されたシャード表、およびすべてのシャードにレプリケートされる重複表が含まれています。重複表には参照情報が含まれています(たとえば、各シャードで共通のStock Items表)。シャード表と重複表の組合せによって、シャーディング・キーに関連付けられているすべてのトランザクションを単一のシャードで処理できます。この技法によって、線形のスケーラビリティおよび障害の分離が可能になります。

重複表が必要な例として、シャード表ファミリで説明される表ファミリを取り上げます。データベース・スキーマにはProducts表も含まれる可能性があり、この表には、この表ファミリに対して作成されたシャード内のすべての顧客が共有するデータが含まれますが、顧客番号でシャーディングすることはできません。注文処理中のマルチシャード問合せを回避するため、表全体をすべてのシャードに複製する必要があります。

シャード表(Customers、OrdersおよびLineItems)と重複表(Products)の違いを次の図に示します。

図2-1 SDBのシャード表と重複表

図2-1の説明が続きます
「図2-1 SDBのシャード表と重複表」の説明

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の実行

SDBにスキーマを作成するには、シャード・カタログ・データベースでDDLコマンドを発行する必要があります。シャード・カタログ・データベースは、DDLを検証し、それらを最初にローカルで実行します。このため、シャード・カタログ・データベースには、シャード・データベースに存在するすべてのオブジェクトのローカル・コピーが含まれており、SDBのスキーマのマスター・コピーとして機能します。カタログの検証およびDDLの実行が成功した場合、そのDDLはすべてのシャードに自動的に伝播され、シャード・カタログで発行された順序で適用されます。

DDLの伝播中にシャードが停止しているか、アクセスできない場合、カタログはそのシャードに適用できなかったDDLを追跡し、そのシャードがアクセス可能になったときにそれらを適用します。新しいシャードがSDBに追加された場合、クライアントがアクセスできるようになる前に、SDBで実行されたすべてのDDLがそのシャードに同じ順序で適用されます。

SDBで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を参照してください。

スキーマ・オブジェクトを作成するためにSDBユーザーを作成する

シャード・カタログ・データベースにのみ存在するローカル・ユーザーには、SDBにスキーマ・オブジェクトを作成するための権限がありません。このため、SDBスキーマを作成するための最初のステップは、SYSDBAとしてシャード・カタログ・データベースに接続し、SHARD DDLを有効にして、CREATE USERコマンドを実行することによって、SDBユーザーを作成することです。SDBユーザーがカタログ・データベースに接続すると、SHARD DDLモードがデフォルトで有効になります。

ノート:

ローカル・ユーザーは、SHARD DDLモードを有効にしている場合、非スキーマSDBオブジェクト(表領域、ディレクトリ、コンテキストなど)を作成できます。ただし、スキーマSDBオブジェクト(表、ビュー、索引、ファンクション、プロシージャなど)は作成できません。

シャード・オブジェクトは、ローカル・オブジェクトに対する依存性を持つことができません。たとえば、ローカル表にすべてのシャードを表示するビューを作成することはできません。

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のみが適用されます。

シャード・データベースのためのDDL構文の拡張

Oracle ShardingのためにSQL DDL文に変更が加えられました。この構文を持つDDL文は、シャード・データベースに対してのみ実行できます。

Oracle Shardingをサポートするために問合せおよびDML文を変更する必要はなく、DDL文の変更も非常に限られています。ほとんどの既存のDDL文は、通常のOracle Databaseと同じ構文およびセマンティクスを使用して、シャード・データベースで同様に機能します。

CREATE TABLESPACE SET

これはOracle Shardingのために導入された新しい文です。構文はCREATE TABLESPACEと似ています。

CREATE TABLESPACE SET tablespace_set 
	   [IN SHARDSPACE shardspace]
      		[USING TEMPLATE (
    { MINIMUM EXTENT size_clause
    | BLOCKSIZE integer [ K ]
    | logging_clause
    | FORCE LOGGING
    | ENCRYPTION tablespace_encryption_spec
    | DEFAULT [ table_compression ] storage_clause
    | { ONLINE | OFFLINE }
    | extent_management_clause
    | segment_management_clause
    | flashback_mode_clause
    }...
   )];

この文は、1つ以上のシャード表および索引の論理ストレージ・ユニットとして使用できる表領域セットを作成します。表領域セットは、シャード領域のシャード間に分散された複数のOracle表領域で構成されます。

システム管理のシャーディングでは、シャード・データベースにデフォルトの1つのシャード領域のみがあります。表領域セット内の表領域の数は自動的に決定され、対応するシャード領域内のチャンクの数と同じです。

表領域セット内のすべての表領域はビッグファイルであり、プロパティが同じです。プロパティはUSING TEMPLATE句に指定します。この句は、通常の表領域のpermanent_tablespace_clauseと同じですが、datafile_tempfile_spec句にデータファイル名を指定できないことが異なります。表領域セット内の各表領域のデータファイル名は自動的に生成されます。

表領域セットは永続表領域のみで構成され、システム、UNDOまたは一時表領域セットはありません。

CREATE TABLESPACE SET TSP_SET_1 IN SHARDSPACE sgr1 
USING TEMPLATE
( DATAFILE SIZE 100m
  EXTEND MANAGEMENT LOCAL
  SEGMENT SPACE MANAGEMENT AUTO
);

ALTER TABLESPACE SET

表領域セットのシャード領域のプロパティは変更できません。表領域セットの他のすべての属性は、通常の永続表領域と同様に変更できます。表領域セット内の表領域はビッグファイルであるため、ADD DATAFILE句およびDROP DATAFILE句はサポートされません。

DROP TABLESPACE SETおよびPURGE TABLESPACE SET

これらの文の構文およびセマンティクスは、DROP文およびPURGE TABLESPACE文と似ています。

CREATE TABLE

この文は、シャード表と重複表の作成および表ファミリの指定ができるように拡張されました。

構文

CREATE [ { GLOBAL TEMPORARY | SHARDED | DUPLICATED} ] 
	     TABLE [ schema. ] table
      { relational_table | object_table | XMLType_table }
      	[ PARENT [ schema. ] table ] ;

CREATE TABLE文の次の部分は、Oracle Shardingをサポートするためのものです。

  • SHARDEDキーワードおよびDUPLICATEDキーワードは、表のコンテンツがシャード間でパーティション化されるか、すべてのシャードで複製されることをそれぞれ示します。DUPLICATEDキーワードは、重複表を作成するための唯一の構文の変更です。以降で説明する他のすべての変更はシャード表にのみ適用されます。

  • PARENT句は、シャード表を表ファミリのルート表にリンクします。

  • シャード表を作成するには、TABLESPACEのかわりにTABLESPACE SETを使用します。TABLESPACEが含まれるすべての句は、TABLESPACE SETが含まれるように拡張されました。

  • 3つの句: table_partitioning_clauses内のconsistent_hash_partitionsconsistent_hash_with_subpartitionsおよびpartition_set_clause

    table_partitioning_clauses ::=
    {range_partitions
    | hash_partitions
    | list_partitions
    | composite_range_partitions
    | composite_hash_partitions
    | composite_list_partitions
    | reference_partitioning
    | system_partitioning
    | consistent_hash_partitions
    | consistent_hash_with_subpartitions
    | partition_set_clause
    }

現在のリリースでのシャード表に関する制限:

  • シャード表のデフォルトの表領域セットはありません。

  • 一時表はシャーディングまたは複製できません。

  • 索引構成シャード表はサポートされません。

  • シャード表には、ネストした表の列またはアイデンティティ列を含めることはできません。

  • シャード表に定義される主キー制約には、シャーディング列を含める必要があります。重複表の列を参照するシャード表の列の外部キー制約はサポートされていません。

  • システム・パーティション化および間隔レンジ・パーティション化は、シャード表ではサポートされません。個別のハッシュ・パーティションの指定は、コンシステント・ハッシュによるパーティション化ではサポートされません。

  • PARTITION BY句またはPARTITIONSET BY句に使用されるシャード表の列には、仮想列を指定できません。

現在のリリースの重複表では、次のことはサポートされません。

  • システム・パーティション表および参照パーティション表

  • LONG、抽象(MDSYSデータ型はサポートされています)、REFデータ型

  • 主キーを除く列の最大数は999個です

  • nologgingparallelinmemoryオプション

  • 重複表のXMLType列は非ASSM表領域で使用できません

CREATE SHARDED TABLE customers 
( cust_id     NUMBER NOT NULL
, name        VARCHAR2(50)
, address     VARCHAR2(250) 
, location_id VARCHAR2(20)
, class       VARCHAR2(3)
, signup_date DATE
,
CONSTRAINT cust_pk PRIMARY KEY(cust_id, class)
)
PARTITIONSET BY LIST (class)
PARTITION BY CONSISTENT HASH (cust_id)
PARTITIONS AUTO
(PARTITIONSET gold   VALUES (‘gld’) TABLESPACE SET ts2,
 PARTITIONSET silver VALUES (‘slv’) TABLESPACE SET ts1)
;

ALTER TABLE

次のオプションは、システム管理またはコンポジット・シャード・データベースのシャード表ではサポートされません。

  • 名前変更

  • 外部キー制約の追加

  • 個々のパーティションおよびサブパーティションに対するすべての操作

  • シャードに対するすべてのパーティション関連の操作(TRUNCATE PARTITION、UNUSABLE LOCAL INDEXESおよびREBUILD UNUSABLE LOCAL INDEXESを除く)

次の操作は、重複表ではサポートされていません。

  • データ型: LONG、抽象(MDSYSデータ型はサポートされています)、REF

  • 列のオプション: ベクトル・エンコード、不可視の列、ネストした表

  • オブジェクト型

  • クラスタ化表

  • 外部表

  • ILMポリシー

  • PARENT句

  • 表のフラッシュバック操作

  • システムおよび参照パーティション化

  • nologgingオプションの有効化

  • 表の切捨て

  • 重複表のマテリアライズド・ビュー・ログの削除

  • シャード上の重複表のマテリアライズド・ビューの削除

  • シャード上の(重複表の)マテリアライズド・ビューの変更

ALTER SESSION

セッションレベルのSHARD DDLパラメータは、シャード・カタログ・データベースに対して発行されたDDLのスコープを設定します。

ALTER SESSION { ENABLE | DISABLE } SHARD DDL

SHARD DDLを有効にした場合、セッションで発行されたすべてのDDLはシャード・カタログおよびすべてのシャードで実行されます。SHARD DDLを無効にした場合、DDLはシャード・カタログ・データベースに対してのみ実行されます。SDBユーザー(すべてのシャードおよびカタログに存在するユーザー)の場合、SHARD DDLはデフォルトで有効にされます。SDBユーザーを作成するには、CREATE USERを実行する前に、SHARD DDLパラメータを有効にする必要があります。