ページの先頭行へ戻る
Enterprise Postgres 14 SP1 スケールアウト運用ガイド
FUJITSU Software

5.4.1 全ノードに対するDDL文の実行

オブジェクトを定義するDDL文について、中央管理ノード上でpgx_ddl_target_nodeパラメータに'ALLNODES'を指定して実行することで、クラスタに参加しているすべてのノード上にデータベースオブジェクトを定義できます。

全ノードに対して定義したオブジェクトを、全ノード対象のオブジェクトと言います。

オブジェクトを操作するDDL文の実行対象オブジェクトが、全ノード対象である場合、中央管理ノード上でpgx_ddl_target_nodeパラメータを空、または、'ALLNODES'を指定して実行することで、全ノードに対して該当のDDL文やオブジェクトの操作が実行できます。

例えば、以下のように実行します。

例1:全ノード対象のオブジェクトの定義
SET pgx_ddl_target_node = 'ALLNODES';
CREATE ROLE role_sc;

例2:全ノード対象のオブジェクトの変更
SET pgx_ddl_target_node = ''; //または、SET pgx_ddl_target_node = 'ALLNODES'
ALTER ROLE role_sc LOGIN; //role_scは全ノード対象のオブジェクトのため、全ノードに対して実行される。

例3:全ノード対象のオブジェクトの削除
SET pgx_ddl_target_node = ''; //または、SET pgx_ddl_target_node = 'ALLNODES'
DROP ROLE role_sc; //role_scは全ノード対象のオブジェクトのため、全ノードに対して実行される。

全ノードに対するDDL文は、基本的には個別ノードに対するDDL文と同じ動きをしますが、各DDL文の一部オプションについては、追加の仕様の定義が必要であるため、その仕様を定義します。

実行対象のDDL文

注意

TRUNCATEの対象がレプリケーションテーブルの場合、DDL文が全ノードに実行されるわけではありませんが、レプリケーションの仕組みを使って実行されます。

実行対象外のDDL文

以下のSQLコマンドについては、pgx_ddl_target_nodeを'ALLNODES'に設定し、コマンドを実行した場合、中央管理ノードのみに対して実行されます。全ノードに対しては実行されません。

また、特定のコマンドのVERBOSEオプションについては、全ノードに対して実行はできますが、中央管理ノード上で各ノードの出力結果を表示できません。

スケールアウトのシャードとレプリケーションテーブルについては、DDLの一元実行機能としては、全ノードに対しては実行されませんが、それぞれの機能にて、適切なノードに対して処理が行われます。

以下の例では、COMMIT/ROLLBACKは、すべて中央管理ノードのみで実行されます。

全ノードや個別のデータノードに対して実行されたDDL文は、中央管理ノード上でのCOMMIT/ROLLBACK実行に併せてCOMMIT/ROLLBACKが実行されることに注意してください。

SET pgx_ddl_target_node = '';
BEGIN;
CREATE TABLE tblcoord (a int);
SET pgx_ddl_target_node = 'ALLNODES';
CREATE TABLE tblallnodes (a int);
COMMIT; //tblcoordが中央管理ノード上、tblallnodesが全ノード上でコミットされる

SET pgx_ddl_target_node = '';
BEGIN;
CREATE TABLE tblcoord (a int);
SET pgx_ddl_target_node = 'ALLNODES';
CREATE TABLE tblallnodes (a int);
ROLLBACK; //tblcoordが中央管理ノード上、tblallnodesが全ノード上でロールバックされる。

SET pgx_ddl_target_node = '';
BEGIN;
CREATE TABLE tblcoord (a int);
SET pgx_ddl_target_node = 'ALLNODES';
CREATE TABLE tblallnodes (a int);
SET pgx_ddl_target_node = '';
COMMIT; //tblcoordが中央管理ノード上、tblallnodesが全ノード上でコミットされる。

SET pgx_ddl_target_node = '';
BEGIN;
CREATE TABLE tblcoord (a int);
SET pgx_ddl_target_node = 'datanode1';
CREATE TABLE tbldn1 (a int);
ROLLBACK; //tblcoordが中央管理ノード上、tbldn1がdatanode1上でロールバックされる。

各種オプション指定時の動作

全ノードに対するDDL文の実行時にオプションを指定した場合、以下のように動作します。

CREATE系のIF NOT EXISTSの動作

一部のノードに同名のオブジェクトが存在する場合でもエラーにはなりません。

同名のオブジェクトが存在しないノードにはオブジェクトを定義し、同名のオブジェクトが存在するノードについては、注意メッセージが発行されます。

なお、中央管理ノードに、すでにオブジェクトが存在した場合、そのオブジェクトが全ノード対象かどうかの値は変更されません。また、中央管理ノードにオブジェクトが存在せず、データノードに、すでにオブジェクトが存在した場合、中央管理ノードには、全ノード対象のオブジェクトが作成されます。今後、中央管理ノード上でそのオブジェクトへの操作は全ノード対象となるため、データノードに、すでに存在していたオブジェクトも操作の対象となることに注意してください。

ALTER時のIF EXISTSの動作

一部のノード上でオブジェクトが存在しない場合でもエラーにはなりません。

オブジェクトが存在するノードではオブジェクトを変更し、オブジェクトが存在しないノードについては、注意メッセージが発行されます。

また、中央管理ノード以外の一部のデータノードにオブジェクトが定義されている場合、中央管理ノードでpgx_ddl_target_node = 'ALLNODES'とし、ALTER ... IF EXISTSを実行することで、それらのデータノードに定義されたオブジェクトを変更することができます。

DROP時のIF EXISTSの動作

一部のノード上でオブジェクトが存在しない場合でもエラーにはなりません。

オブジェクトが存在するノードではオブジェクトを削除し、オブジェクトが存在しないノードについては、注意メッセージが発行されます。

また、中央管理ノード以外の一部のデータノードにオブジェクトが定義されている場合、中央管理ノードでpgx_ddl_target_node = 'ALLNODES'とし、DROP ... IF EXISTSを実行することで、それらのデータノードに定義されたオブジェクトを削除することができます。

CASCADEの動作

全ノード対象のオブジェクトについて、中央管理ノード上とデータノード上で依存関係が異なっていた場合でも、処理を実施します。

DDL文実行に関する共通事項

DDL文実行に関する共通事項として、以下があります。

DDL文の動作

個別のDDL文について、上記以外の項目に関する仕様や動作を以下に示します。

ALTER SYSTEM

設定パラメータの変更は全ノードに対して実行可能です。

ALTER SYSTEMで設定された値は、次回のサーバ設定の再ロードで、またサーバ開始時にのみ変更可能なパラメータについては次回のサーバ再起動で有効になります。再ロード、サーバ再起動は、各ノードにて個別に実施してください。

DROP ROLE

全ノード対象のロールについて、中央管理ノード上にそのロールに対する共有ユーザーマッピングが自動で作成されている場合があります。その場合、中央管理ノード上でロールを削除する前に、共有ユーザーマッピングを削除してください。共有ユーザーマッピングは、全データノードと、特別なエントリ"ALLNODES"に対して作成されているため、それらをすべて削除する必要があります。以下のように削除してください。

SET pgx_ddl_target_node = 'COORDINATOR';
DROP USER MAPPING FOR ユーザー名 PGXNODE データノード名1;
DROP USER MAPPING FOR ユーザー名 PGXNODE データノード名2;
...
DROP USER MAPPING FOR ユーザー名 PGXNODE "ALLNODES";
GRANT/REVOKE

GRANT ... TO role_specification [, ...]/REVOKE ... FROM role_specification [, ...]に指定したrole_specificationが、全ノード対象のロールである場合、全ノードに対してDDL文が実行されます。

例えば、全ノード対象のロールrole_all に対し、中央管理ノード上のみで定義されたPGXNODE datanode1の権限を付与する場合については、上記の点に注意してください。

これを実現するための方法について、以下に例を示します。

SET pgx_ddl_target_node = 'COORDINATOR'; //GRANT文が、中央管理ノード上のみで実行されるようpgx_ddl_target_nodeの値をCOORDINATORに設定する。
GRANT ALL ON PGXNODE datanode1 TO role_all;
RESET pgx_ddl_target_node;

設定パラメータによる影響

ノードごとに以下のパラメータの値が異なる場合、ノードごとに実施されるDDLの結果が異なってしまいます。

この問題を回避するためには、すべてのノード上でこれらのパラメータの値を同じに設定してください。ただし、中央管理ノード上でSETコマンドでパラメータを変更したとしても、それらは全ノードに伝搬されないことに注意してください。

あるいは、search_path, default_table_access_method, default_tablespace, default_toast_compression, temp_tablespacesについては、DDL実行時に特定のオプションの値が未指定の場合のデフォルトの値を決定するパラメータであるため、DDL実行時に特定のオプションの値を指定することで、上記の問題を回避できます。


search_path

DDLの一元実行では、データノードに対するDDLの実行時に、DDL実行時の中央管理ノード上でのsearch_pathと同じ値をデータノードへの接続に対し設定し、実行します。

この際、以下のようなDDL文の実行時に、ユーザーの意図した動作にならない可能性があることに注意してください。

SET pgx_ddl_target_node = 'ALLNODES';
CREATE VIEW view AS SELECT * FROM table;
  • 中央管理ノード上のsearch_pathが$user,public

  • 中央管理ノード上のpublicスキーマにのみ、tableが存在

  • データノード上の$userスキーマとpublicスキーマそれぞれに、tableが存在


上記の例では、中央管理ノードではpublicスキーマのtableを基にviewが作成されるのに対し、データノードでは$userスキーマのtableを基にviewが作成されます。これはユーザーの意図に反したものとなると考えられます。

そうした挙動を避けるためには、実行対象となるオブジェクトに対し、適切なスキーマ名を付与し、DDL文を実行してください。

例えば上記の例に対して、ユーザーの意図通りに実行されるDDL文は、以下のようになります。

CREATE VIEW public.view AS SELECT * FROM public.table;

全ノードに対するDDL文実行の失敗

全ノードに対するDDL文の実行は、基本的には、PostgreSQLの二相コミットを利用して実現します。二相コミットを利用する場合、全ノードに対するDDL文の実行に対して一部のノードで実行に失敗した場合は、全ノードで実行が失敗となります。停止中のノードが存在する場合にも、全ノードに対するDDL文は実行に失敗します。

全ノードに対してオブジェクトを定義したい場合は、停止中のノードを起動させてから全ノードに対するDDL文を実行してください。

トランザクションブロック内で実行できないDDL文については、二相コミットを利用することができないため、DDL文の実行失敗時に全ノードで実行失敗となりません。この場合は、手動で定義情報の修正を行ってください。

定義情報の修正

二相コミットを利用しない全ノードに対するDDL文の実行が失敗した場合は、一部のノードで実行が失敗し、一部のノードで実行が成功した状態になっています。

この場合、全ノードに対して失敗した状態になるように、手動で定義状態の回復を試みてください。または、全ノードに対して成功した状態になるように、エラーの原因を取り除いた後に、DDL文を再実行してください。

どちらの方法が可能かは、実行するDDL文に依存します。

実行結果の確認

DDL文の実行に失敗した場合、失敗したノードとそのエラー内容を返却します。また、手動で対処が必要なノードについては、その対処内容を表示します。失敗したノード、対処が必要なノードすべてについて、エラー内容や対処内容を表示します。

ただし、中央管理ノードのダウンによりDDL文の実行に失敗した場合は、結果が返却されません。

この場合は、全ノードに対する操作が成功したかを確認してください。

CREATE系のコマンドの場合
  • CREATE TABLESPACE, CREATE DATABASE

    中央管理ノード上でオブジェクトが定義されているかを確認してください。

    定義されている場合、全ノードに対する定義が成功しています。

    定義されていない場合は、各データノード上でDDL文の実行に成功したかを個別に確認する必要があります。

    実行に成功したかを確認するためには、期待通りに定義が成功しているかを確認するコマンドを実行してください。

ALTER系のコマンドの場合

各データノード上でDDL文の実行に成功したかを個別に確認する必要があります。

実行に成功したかを確認するためには、期待通りに定義が変更されているかを確認するコマンドを実行してください。

DROP系のコマンドの場合

中央管理ノード上でオブジェクトが定義されているかを確認してください。

オブジェクトが定義されている場合、全ノード上からのオブジェクト削除に失敗しています。

定義情報の修正方法

CREATE系のDDL文

CREATE TABLESPACE, CREATE DATABASEは定義情報の修正が必要な場合があります。

対処が必要なノードについて、作成したオブジェクトの削除を行ってください。DDL文の実行失敗時には自動的な対処を試みますが、それが失敗した場合は、手動で行う必要があります。

具体的には、各ノードに対し、DROP文を実行するか、中央管理ノードでpgx_ddl_target_node = 'ALLNODES'として、DROP ... IF EXISTSを実行してください。

ALTER系のDDL文

ALTER DATABASE SET TABLESPACEは定義情報の修正が必要な場合があります。

全ノードで失敗した状態になるように、実行が成功したノードについて、変更された定義情報を変更前の状態に戻してください。

または、実行失敗のエラーの原因を取り除いた後に、中央管理ノードに対してDDL文を再実行してください。既に定義が変更されたノードに対してDDL文が実行された場合は、同じ変更が再度実施されます。エラーにはなりません。

DROP系のDDL文

DROP TABLESPACE,DROP DATABASE,DROP SUBSCRIPTIONは定義情報の修正が必要な場合があります。

全ノードで成功した状態になるように、実行失敗のエラーの原因を取り除いた後に、中央管理ノードに対してDDL文を再実行してください。その際、既に削除されたノードに対してDDL文が実行された場合は、既に削除されましたとの警告が発生します。エラーにはなりません。

全ノードに対するDDL文実行に関する補足

全ノードに対する定義情報について、各ノード上に定義された定義情報を個別に変更することは推奨されません。

個別のノードに対するDDL文の実行により、そのノード上の定義情報を変更することは可能ですが、変更後、その定義情報に関与する、全ノードに対するDDL文の実行が失敗する可能性があります。