DDL replication¶
DDLはデータ定義言語の略で、データベースオブジェクトを作成、変更、および削除するSQL言語のサブセットです。
操作の利便性と正確さのために、PGDはほとんどのDDLアクションをレプリケートしますが、次の例外があります。
一時的またはログされていない関係
特定のDDLステートメント(ほとんどが長時間実行)
ロックコマンド(
LOCK)テーブルメンテナンスコマンド(
VACUUM、ANALYZE、CLUSTER、REINDEX)autovacuumのアクション
操作コマンド(
CHECKPOINT、ALTER SYSTEM)
・ データベースまたはテーブルスペースに関するアクション
自動DDLレプリケーションにより、 DDL変更をすべてのノードに手動で配布し、それらの一貫性を保証することなく、特定のDDL変更が簡単になります。
デフォルトのレプリケーションセットでは、デフォルトでDDLがすべてのノードにレプリケートされます。 DDLをレプリケートするには、 DDLレプリケーションフィルタをレプリケーションセットに追加する必要があります。
DDL replication filtering を参照してください。
PGDは、 DDLレプリケーションに関しては、スタンドアロンのPostgreSQLとは大きく異なります。それを同じように扱うことは、PGDの最も一般的な問題です。
テーブルレプリケーションとの主な違いは、 DDLレプリケーションはDDLの結果ではなくステートメント自分自身をレプリケートすることです。これはほとんどの場合非常にうまく機能しますが、 DDLはすべてのノードで同様に実行する必要があるという要件が導入されます。より微妙な点は、 DDLは、拡張機能(ビルトインではない)によって導入されたデータ型を含む、すべてのデータ型固有のパラメーター設定に関して不変でなければならないということです。たとえば、 DDLステートメントは、各ノードで使用されるデフォルトのエンコーディングで正しく実行する必要があります。
DDLレプリケーションオプション¶
bdr.ddl_replication
パラメーターは、レプリケーションの動作を指定します。
bdr.ddl_replication = on はデフォルトであり、
DDLをデフォルトのレプリケーションセット、デフォルトではすべてのノードを意味します。デフォルト以外のレプリケーションセットは、
DDL filter がない限りDDLをレプリケートしません
それらのために定義されています。
関数bdr.replicate_ddl_command()
を使用して、特定のレプリケーションセットにDDLをレプリケートすることもできます。これは、ノードがダウンしているときにDDLコマンドを実行する場合、またはノードまたは担当者セットのサブセット、たとえばsite1のすべてのノードに存在するインデックスまたはパーティションが必要な場合に役立ちます。
SELECT bdr.replicate_ddl_command(
CREATE INDEX CONCURRENTLY ON foo (col7);,
ARRAY[site1], -- the replication sets
on); -- ddl_locking to apply
お勧めしませんが、自動DDLレプリケーションをスキップし、
bdr.ddl_replication
構成パラメーターを使用して各ノードで手動で実行できます。
SET bdr.ddl_replication = off;
設定すると、PGDはグローバルロックと実行されたDDLコマンドのレプリケーションの両方をスキップします。次に、すべてのノードでDDLを手動で実行する必要があります。
警告
グローバルロックせずに各ノードでDDLを手動で実行すると、競合するDDLまたはDMLが同時に実行されている場合、PGDグループ全体がレプリケーションを停止する可能性があります。
bdr.ddl_replication パラメーターは、
bdr_superuser、スーパーユーザー、またはconfig
ファイルでのみ設定できます。
PGDシステムでDDLを実行する¶
PGDグループは、スタンドアロンのPostgreSQLサーバーと同じではありません。これは、中央ロックとトランザクションコーディネーターのない非同期マルチマスターレプリケーションに基づいています。これは、 DDLの実行時に重要な意味を持ちます。
並列実行されるDDLは、PGDでも引き続き実行されます。 DDL実行は、実行時に各ノードでのパラレル操作に影響を与えるパラメーターを尊重するため、ノード間の設定の違いに気付く場合があります。
競合するDDLの実行を防止します。そうしないと、 DDLレプリケーションによりエラーが発生し、レプリケーションが停止します。
PGDは、これらの問題に対して3つのレベルの保護を提供します。
ddl_locking = 'dml'
は、一度に1つのノードからのみDDLを実行する場合に使用可能な操作に最適なオプションです。これはデフォルトではありませんが、
DDLの実行元を制御できる場合は、この設定を使用することをお勧めします。そうすることで、ノード間の競合がないことが保証されます。ノード内の競合は、PostgreSQLによってすでに処理されています。
ddl_locking = on は最も厳密なオプションであり、
DDLが任意のノードから同時に実行される可能性があり、正確性を保証したい場合に最適です。
ddl_locking = off
は最も厳密でないオプションであり、一般的な使用では危険です。このオプションはロックを完全にスキップし、パフォーマンスのオーバーヘッドを回避するため、新しい空のデータベーススキーマを作成するときに便利なオプションになります。
これらのオプションは、
bdr_superuser、スーパーユーザー、またはconfig file
でのみ設定できます。
bdr.replicate_ddl_command
を使用する場合、その関数に渡されたDDLコマンドに対してのみ指定されたbdr.ddl_locking
設定を使用して、3番目の引数でこのパラメーターを直接設定できます。
DDLロックの詳細¶
2種類のロックは、PGDでレプリケートされたDDLの正確性を強制します。
最初の種類はグローバルDDLロックと呼ばれ、 ddl_locking = on
の場合にのみ使用されます。グローバルDDLロックは、各DDLステートメントの実行中に、他のDDLがクラスターで実行されるのを防ぎます。これにより、一般的なケースでは完全な正確さが保証されますが、多くの単純なケースでは厳しすぎます。
PGDは、スキーマが変更されるトランザクションで初めて、
DDL操作のグローバルロックを取得します。これにより、クラスター内のDDL実行トランザクションが効果的にシリアル化されます。言い換えれば、
DDLの実行中は、異なるテーブルに影響を与える場合でも、ノード上の他の接続は別のDDLコマンドを実行できません。
DDL操作のロックを取得するために、 DDLを実行する排他的権利を付与するように要求します。ロック要求は通常のレプリケーションストリームによって送信され、ノードもレプリケーションストリームによって応答します。したがって、ノード(または少なくとも大部分のノード)がレプリケーションの遅延を大きくせずに実行することが重要です。そうしないと、ノードがDDLロックを取得するまでに時間がかかる場合があります。大多数のノードが同意すると、 DDL実行が実行されます。
DDLロックの順序は、Raftプロトコルを使用して決定されます。 1つのノードで実行されるDDLステートメントは、他のすべてのノードで同じ順序で実行されます。
DDLを実行しているノードがクラスターで実行された以前のすべてのDDLの効果を確認したことを確認するために、以前のDDLを実行したノードに追いつくまで待機します。現在のDDLを実行しているノードが、前のDDLを実行したノードに対してレプリケーションが遅れている場合、ロックの取得に時間がかかる場合があります。したがって、単一のノード、または他のノードで発生したレプリケーションの変更にほぼ追いついたノードからDDLを実行することをお勧めします。
2番目の種類は、グローバルDMLロックまたはリレーションDMLロックと呼ばれます。この種のロックは、
ddl_locking = on またはddl_locking = dml
のいずれかに使用され、
DDLステートメントにより、進行中のDMLステートメントが失敗する可能性があります。これらのエラーは、ユニーク制約、チェック制約、
NOT NULL
制約などの制約を追加または変更したときに発生する可能性があります。リレーションDMLロックは、一度に1つのリレーションにのみ影響します。リレーションDMLロックは、レプリケーションがエラーで停止する可能性のある変更がキューにある間、
DDLが実行されないようにします。
テーブルのグローバルDMLロックを取得するには、 DDLを実行しているPGDノードがPGDグループ内の他のすべてのノードに連絡し、書き込みに対してテーブルをロックし、そのテーブルへの保留中の変更がすべて排出されるまで待機するように要求します。すべてのノードが完全に追いつくと、DMLロックの発信者は自由にテーブルのスキーマ変更を実行し、他のノードにレプリケートできます。
グローバルDMLロックは、各ノードのテーブルに EXCLUSIVE LOCK を保持するため、実行中にそのテーブルに対するDML、他のDDL、VACUUM、およびインデックスコマンドをブロックします。これは、通常 EXCLUSIVE LOCK以上をとらないコマンドに対してグローバルDMLロックが保持されている場合でも当てはまります。
保留中のDML操作が排出されるのを待機すると、時間がかかり、レプリケーションが現在遅れている場合はさらに時間がかかる場合があります。これは、データの変更とは異なり、行の表現と制約に影響を与えるスキーマの変更は、構成されたすべてのノードに到達でき、現在の書き込み速度にかなりうまく対応している場合にのみ実行できることを意味します。ノードがダウンしているときにそのようなDDLコマンドを実行する必要がある場合は、最初にダウンしているノードを構成から削除します。
DDLステートメントがレプリケートされない場合、グローバルロックは取得されません。
PGDシステムでDDLを実行する で説明されているように、ロック動作は
bdr.ddl_locking
パラメーターで指定されます。
ddl_locking = onはグローバルDDLロックを取得し、必要に応じてリレーションDMLロックを取得します。ddl_locking = dmlは、グローバルDDLロックをスキップし、必要に応じて、リレーションDMLロックを取得します。ddl_locking = offは、グローバルDDLロックとリレーションDMLロックの両方をスキップします。
一部のPGD関数は、 DDLを変更します。これらの関数には、各関数のドキュメントに記載されているDDLロック動作が適用されます。
したがって、 ddl_locking = dml
は、競合するDDLが他のノードから実行されないことが保証できる場合にのみ安全です。この設定では、グローバルDDLロックのみを必要とするステートメントは、グローバルロックをまったく使用しません。
ddl_locking = off は、競合するDDLがなく、
DDLが実行されるデータベースオブジェクトで競合するDML操作がないことを保証できる場合にのみ安全です。ロックをオフにしてから問題が発生した場合、データへの進行中の変更が失われる可能性があります。ユーザーアプリケーションチームは、発生した問題を解決する必要があります。
場合によっては、同時に実行されるDDLを適切にシリアル化できます。これらのシリアル化の失敗が発生すると、 DDLが再実行される場合があります。
DDLレプリケーションは、昇格するまでロジカルスタンバイノードでアクティブになりません。
一部のPGD管理機能はDDLのように動作します。つまり、グローバルロックを取得しようとし、 DDLレプリケーションがアクティブな場合、アクションがレプリケートされます。レプリケートされた関数の完全なリストは、
DDLのように動作するPGD関数 にリストされています。
一時テーブルで実行されるDDLは、グローバルロックを必要としません。
現在のトランザクションで作成されたオブジェクトのALTERまたはDROPには、グローバルDMLロックは必要ありません。
- グローバルDDLロックおよびグローバルDMLロックのモニタリングは、
Monitoring に示されています。
DDLの影響の最小化¶
あらゆるデータベースに対する優れた運用上のアドバイス、これらの点はPGDではさらに重要になります。
DDLの影響を最小限に抑えるには、 DDLを実行するトランザクションを短くし、多くの行の変更と組み合わせないで、長時間実行される外部キーまたはその他の制約の再チェックを避けます。
ALTER TABLEの場合、ADD CONSTRAINTを単独で使用するのではなく、ADD CONSTRAINT NOT VALIDを使用してから、VALIDATE CONSTRAINTを使用した別のトランザクションを使用します。VALIDATE CONSTRAINTは、すべてのノードで再生されるまで待機します。これにより、確認を受け取るまでに顕著な遅延が発生します。インデックスを作成するときは、可能な限り
CONCURRENTLYオプションを使用します。
実行時間の長いDDLを実行する別の方法は、 DDLレプリケーションを無効にしてから、各ノードでDDLステートメントを個別に実行することです。次の例に示すように、単一のSQLステートメントを使用してこれを行うこともできます。グローバルロックルールは引き続き適用されるため、このタイプの使用で自分自身をロックアウトしないように注意してください。これはより多くの回避策です。
SELECT bdr.run_on_all_nodes($ddl$
CREATE INDEX CONCURRENTLY index_a ON table_a(i);
$ddl$);
bdr.run_on_all_nodes() テクニックをCREATE INDEX CONCURRENTLY
で使用することをお勧めします。 CREATE INDEX CONCURRENTLY
はマルチトランザクションコマンドであるため、セッション全体でDDLレプリケーションを無効にする必要があることに注意してください。実行中の書き込みを防止するため、実稼働システムでCREATE INDEX
を避けてください。 REINDEX
は3.6までのバージョンで複製されましたが、PGD 3.7以降では複製されません。
REINDEX が保持するAccessExclusiveLocksのため、 REINDEX
の使用を避けてください。
代わりに、PG12+または2QPG11+で利用可能なREINDEX CONCURRENTLY
(またはreindexdb --concurrently )を使用してください。
次のようなコマンドラインユーティリティを使用する場合、 DDLレプリケーションを無効にできます。
$ export PGOPTIONS="-c bdr.ddl_replication=off"
$ pg_restore --section=post-data
複数のDDLステートメントは、個々のステートメントとして起動されるのではなく、単一のトランザクションにまとめる方が役立つ場合があるため、 DDLロックは1回だけ取得します。テーブルレベルのロックが通常の操作を妨げる場合、これは望ましくない場合があります。
DDLがシステムを長時間保持している場合は、
psqlまたはpg_cancel_backend() で Control-C
を使用して、元のノードでDDLを安全にキャンセルできます。他のノードからDDLロックをキャンセルすることはできません。
オプションのグローバルロックタイムアウト設定を使用して、グローバルロックにかかる時間を制御できます。
bdr.global_lock_timeout
は、グローバルロックを取得するための待機がキャンセルされるまでにかかる時間を制限します。
bdr.global_lock_statement_timeout
は、グローバルロックを保持するトランザクション内のステートメントの実行時長を制限し、
bdr.global_lock_idle_timeout
は、グローバルロックを保持するトランザクションの最大許容アイドル時間(ステートメント間の時間)を設定します。値をゼロに設定することにより、これらのタイムアウトをすべて無効にできます。
DDL操作が発信元ノードでコミットされると、キャンセルまたは中止することはできません。 PGDグループは、グローバルロックを確認した他のノードに正常に適用され、再生を確認応答するまで待機する必要があります。このため、 DDLトランザクションは短く高速に保ちます。
ダウンノードでのDDLの処理¶
グローバルDDLロックを開始したノードがグローバルロック( DDLまたはDMLのいずれか)を取得した後にダウンした場合、ロックはアクティブなままです。タイムアウトが設定されていても、グローバルロックはタイムアウトしません。ノードが復旧すると、保持しているすべてのグローバルロックを解放します。
長時間または無期限にダウンしたままの場合は、ノードをPGDグループから削除して、グローバルロックを解放します。これが、
bdr_superuserとしてSET コマンドを使用して緊急DDLを実行し、
bdr.ddl_locking 値を更新する理由の1つです。
他のノードの1つがグローバルロックを確認した後、それを取得するコマンドが実行される前にダウンした場合、ロックを要求するそのコマンドの実行は、ノードが稼働しているかのように続行されます。
前述のように、グローバルDDLロックはノードの過半数のみが応答する必要があるため、クラスターの一部がダウンしていても、過半数が実行されていて到達可能である限り機能します。ただし、クラスター全体が利用可能でない限り、DMLロックを取得することはできません。
グローバルDDLまたはグローバルDMLロックを使用すると、別のノードがダウンした場合、コマンドは正常に続行され、ロックが解放されます。
ステートメント固有のDDLレプリケーションに関する懸念¶
すべてのコマンドを自動的に複製できるわけではありません。このようなコマンドは、
bdr.ddl_replication
をオフにしてDDLレプリケーションをオフにしない限り、通常は許可されません。
PGDは、データベースでアクティブになっているときに、一部のDDLステートメントの実行を防ぎます。これにより、正しくレプリケートできないステートメント、またはレプリケーションがまだサポートされていないステートメントを禁止することにより、システムの一貫性が保護されます。
PGDでステートメントが許可されていない場合、多くの場合、同じことを行う別の方法を見つけることができます。たとえば、揮発性のデフォルト値を持つ列を追加するALTER TABLE
を実行することはできません。ただし、一般的には、動作する一連の独立したALTER TABLE
およびUPDATE ステートメントとしてそれを言い換えることができます。
一般に、サポートされていないステートメントの実行は防止され、
feature_not_supported (SQLSTATE 0A000 ) エラーが発生します。
一時オブジェクトを参照または依存するDDLは、PGDによってレプリケートできず、 DDLレプリケーションを有効にして実行するとエラーがスローされます。
PGD DDLコマンド処理マトリックス¶
次の表では、許可されるユーティリティまたはDDLコマンド、レプリケートされるコマンド、およびレプリケート時にかかるグローバルロックの種類について説明します。
ALTER TABLE
のようないくつかのより複雑なステートメントの場合、これらは実行されるサブコマンドによって異なる場合があります。このようなすべてのコマンドには、次の表の下に詳細な説明があります。
Command |
Allowed |
Replicated |
Lock |
|---|---|---|---|
ALTER AGGREGATE |
Y |
Y |
DDL |
ALTER CAST |
Y |
Y |
DDL |
ALTER COLLATION |
Y |
Y |
DDL |
ALTER CONVERSION |
Y |
Y |
DDL |
ALTER DATABASE |
Y |
N |
N |
ALTER DATABASE LINK |
Y |
Y |
DDL |
ALTER DEFAULT PRIVILEGES |
Y |
Y |
DDL |
ALTER DIRECTORY |
Y |
Y |
DDL |
ALTER DOMAIN |
Y |
Y |
DDL |
ALTER EVENT TRIGGER |
Y |
Y |
DDL |
ALTER EXTENSION |
Y |
Y |
DDL |
ALTER FOREIGN DATA WRAPPER |
Y |
Y |
DDL |
ALTER FOREIGN TABLE |
Y |
Y |
DDL |
ALTER FUNCTION |
Y |
Y |
DDL |
ALTER INDEX |
Y |
Y |
DDL |
ALTER LANGUAGE |
Y |
Y |
DDL |
ALTER LARGE OBJECT |
N |
N |
N |
ALTER MATERIALIZED VIEW |
Y |
N |
N |
ALTER OPERATOR |
Y |
Y |
DDL |
ALTER OPERATOR CLASS |
Y |
Y |
DDL |
ALTER OPERATOR FAMILY |
Y |
Y |
DDL |
ALTER PACKAGE |
Y |
Y |
DDL |
ALTER POLICY |
Y |
Y |
DDL |
ALTER PROCEDURE |
Y |
Y |
DDL |
ALTER PROFILE |
Y |
Y |
|
ALTER PUBLICATION |
Y |
Y |
DDL |
ALTER QUEUE |
Y |
Y |
DDL |
ALTER QUEUE TABLE |
Y |
Y |
DDL |
ALTER REDACTION POLICY |
Y |
Y |
DDL |
ALTER RESOURCE GROUP |
Y |
N |
N |
ALTER ROLE |
Y |
Y |
DDL |
ALTER ROUTINE |
Y |
Y |
DDL |
ALTER RULE |
Y |
Y |
DDL |
ALTER SCHEMA |
Y |
Y |
DDL |
ALTER SEQUENCE |
Y |
DML |
|
ALTER SERVER |
Y |
Y |
DDL |
ALTER SESSION |
Y |
N |
N |
ALTER STATISTICS |
Y |
Y |
DDL |
ALTER SUBSCRIPTION |
Y |
Y |
DDL |
ALTER SYNONYM |
Y |
Y |
DDL |
ALTER SYSTEM |
Y |
N |
N |
ALTER TABLE |
Y |
||
ALTER TABLESPACE |
Y |
N |
N |
ALTER TEXT SEARCH CONFIGURATION |
Y |
Y |
DDL |
ALTER TEXT SEARCH DICTIONARY |
Y |
Y |
DDL |
ALTER TEXT SEARCH PARSER |
Y |
Y |
DDL |
ALTER TEXT SEARCH TEMPLATE |
Y |
Y |
DDL |
ALTER TRIGGER |
Y |
Y |
DDL |
ALTER TYPE |
Y |
Y |
DDL |
ALTER USER MAPPING |
Y |
Y |
DDL |
ALTER VIEW |
Y |
Y |
DDL |
ANALYZE |
Y |
N |
N |
BEGIN |
Y |
N |
N |
CHECKPOINT |
Y |
N |
N |
CLOSE |
Y |
N |
N |
CLOSE CURSOR |
Y |
N |
N |
CLOSE CURSOR ALL |
Y |
N |
N |
CLUSTER |
Y |
N |
N |
COMMENT |
Y |
DDL |
|
COMMIT |
Y |
N |
N |
COMMIT PREPARED |
Y |
N |
N |
COPY |
Y |
N |
N |
COPY FROM |
Y |
N |
N |
CREATE ACCESS METHOD |
Y |
Y |
DDL |
CREATE AGGREGATE |
Y |
Y |
DDL |
CREATE CAST |
Y |
Y |
DDL |
CREATE COLLATION |
Y |
Y |
DDL |
CREATE CONSTRAINT |
Y |
Y |
DDL |
CREATE CONVERSION |
Y |
Y |
DDL |
CREATE DATABASE |
Y |
N |
N |
CREATE DATABASE LINK |
Y |
Y |
DDL |
CREATE DIRECTORY |
Y |
Y |
DDL |
CREATE DOMAIN |
Y |
Y |
DDL |
CREATE EVENT TRIGGER |
Y |
Y |
DDL |
CREATE EXTENSION |
Y |
Y |
DDL |
CREATE FOREIGN DATA WRAPPER |
Y |
Y |
DDL |
CREATE FOREIGN TABLE |
Y |
Y |
DDL |
CREATE FUNCTION |
Y |
Y |
DDL |
CREATE INDEX |
Y |
Y |
DML |
CREATE LANGUAGE |
Y |
Y |
DDL |
CREATE MATERIALIZED VIEW |
Y |
N |
N |
CREATE OPERATOR |
Y |
Y |
DDL |
CREATE OPERATOR CLASS |
Y |
Y |
DDL |
CREATE OPERATOR FAMILY |
Y |
Y |
DDL |
CREATE PACKAGE |
Y |
Y |
DDL |
CREATE PACKAGE BODY |
Y |
Y |
DDL |
CREATE POLICY |
Y |
Y |
DML |
CREATE PROCEDURE |
Y |
Y |
DDL |
CREATE PROFILE |
Y |
Y |
|
CREATE PUBLICATION |
Y |
Y |
DDL |
CREATE QUEUE |
Y |
Y |
DDL |
CREATE QUEUE TABLE |
Y |
Y |
DDL |
CREATE REDACTION POLICY |
Y |
Y |
DDL |
CREATE RESOURCE GROUP |
Y |
N |
N |
CREATE ROLE |
Y |
Y |
DDL |
CREATE ROUTINE |
Y |
Y |
DDL |
CREATE RULE |
Y |
Y |
DDL |
CREATE SCHEMA |
Y |
Y |
DDL |
CREATE SEQUENCE |
Y |
DDL |
|
CREATE SERVER |
Y |
Y |
DDL |
CREATE STATISTICS |
Y |
Y |
DDL |
CREATE SUBSCRIPTION |
Y |
Y |
DDL |
CREATE SYNONYM |
Y |
Y |
DDL |
CREATE TABLE |
Y |
DDL |
|
CREATE TABLE AS |
Y |
DDL |
|
CREATE TABLESPACE |
Y |
N |
N |
CREATE TEXT SEARCH CONFIGURATION |
Y |
Y |
DDL |
CREATE TEXT SEARCH DICTIONARY |
Y |
Y |
DDL |
CREATE TEXT SEARCH PARSER |
Y |
Y |
DDL |
CREATE TEXT SEARCH TEMPLATE |
Y |
Y |
DDL |
CREATE TRANSFORM |
Y |
Y |
DDL |
CREATE TRIGGER |
Y |
Y |
DDL |
CREATE TYPE |
Y |
Y |
DDL |
CREATE TYPE BODY |
Y |
Y |
DDL |
CREATE USER MAPPING |
Y |
Y |
DDL |
CREATE VIEW |
Y |
Y |
DDL |
DEALLOCATE |
Y |
N |
N |
DEALLOCATE ALL |
Y |
N |
N |
DECLARE CURSOR |
Y |
N |
N |
DISCARD |
Y |
N |
N |
DISCARD ALL |
Y |
N |
N |
DISCARD PLANS |
Y |
N |
N |
DISCARD SEQUENCES |
Y |
N |
N |
DISCARD TEMP |
Y |
N |
N |
DO |
Y |
N |
N |
DROP ACCESS METHOD |
Y |
Y |
DDL |
DROP AGGREGATE |
Y |
Y |
DDL |
DROP CAST |
Y |
Y |
DDL |
DROP COLLATION |
Y |
Y |
DDL |
DROP CONSTRAINT |
Y |
Y |
DDL |
DROP CONVERSION |
Y |
Y |
DDL |
DROP DATABASE |
Y |
N |
N |
DROP DATABASE LINK |
Y |
Y |
DDL |
DROP DIRECTORY |
Y |
Y |
DDL |
DROP DOMAIN |
Y |
Y |
DDL |
DROP EVENT TRIGGER |
Y |
Y |
DDL |
DROP EXTENSION |
Y |
Y |
DDL |
DROP FOREIGN DATA WRAPPER |
Y |
Y |
DDL |
DROP FOREIGN TABLE |
Y |
Y |
DDL |
DROP FUNCTION |
Y |
Y |
DDL |
DROP INDEX |
Y |
Y |
DDL |
DROP LANGUAGE |
Y |
Y |
DDL |
DROP MATERIALIZED VIEW |
Y |
N |
N |
DROP OPERATOR |
Y |
Y |
DDL |
DROP OPERATOR CLASS |
Y |
Y |
DDL |
DROP OPERATOR FAMILY |
Y |
Y |
DDL |
DROP OWNED |
Y |
Y |
DDL |
DROP PACKAGE |
Y |
Y |
DDL |
DROP PACKAGE BODY |
Y |
Y |
DDL |
DROP POLICY |
Y |
Y |
DDL |
DROP PROCEDURE |
Y |
Y |
DDL |
DROP PROFILE |
Y |
Y |
DDL |
DROP PUBLICATION |
Y |
Y |
DDL |
DROP QUEUE |
Y |
Y |
DDL |
DROP QUEUE TABLE |
Y |
Y |
DDL |
DROP REDACTION POLICY |
Y |
Y |
DDL |
DROP RESOURCE GROUP |
Y |
N |
N |
DROP ROLE |
Y |
Y |
DDL |
DROP ROUTINE |
Y |
Y |
DDL |
DROP RULE |
Y |
Y |
DDL |
DROP SCHEMA |
Y |
Y |
DDL |
DROP SEQUENCE |
Y |
Y |
DDL |
DROP SERVER |
Y |
Y |
DDL |
DROP STATISTICS |
Y |
Y |
DDL |
DROP SUBSCRIPTION |
Y |
Y |
DDL |
DROP SYNONYM |
Y |
Y |
DDL |
DROP TABLE |
Y |
Y |
DML |
DROP TABLESPACE |
Y |
N |
N |
DROP TEXT SEARCH CONFIGURATION |
Y |
Y |
DDL |
DROP TEXT SEARCH DICTIONARY |
Y |
Y |
DDL |
DROP TEXT SEARCH PARSER |
Y |
Y |
DDL |
DROP TEXT SEARCH TEMPLATE |
Y |
Y |
DDL |
DROP TRANSFORM |
Y |
Y |
DDL |
DROP TRIGGER |
Y |
Y |
DDL |
DROP TYPE |
Y |
Y |
DDL |
DROP TYPE BODY |
Y |
Y |
DDL |
DROP USER MAPPING |
Y |
Y |
DDL |
DROP VIEW |
Y |
Y |
DDL |
EXECUTE |
Y |
N |
N |
EXPLAIN |
Y |
||
FETCH |
Y |
N |
N |
GRANT |
Y |
DDL |
|
GRANT ROLE |
Y |
Y |
DDL |
IMPORT FOREIGN SCHEMA |
Y |
Y |
DDL |
LISTEN |
Y |
N |
N |
LOAD |
Y |
N |
N |
LOAD ROW DATA |
Y |
Y |
DDL |
LOCK TABLE |
Y |
N |
|
MOVE |
Y |
N |
N |
NOTIFY |
Y |
N |
N |
PREPARE |
Y |
N |
N |
PREPARE TRANSACTION |
Y |
N |
N |
REASSIGN OWNED |
Y |
Y |
DDL |
REFRESH MATERIALIZED VIEW |
Y |
N |
N |
REINDEX |
Y |
N |
N |
RELEASE |
Y |
N |
N |
RESET |
Y |
N |
N |
REVOKE |
Y |
DDL |
|
REVOKE ROLE |
Y |
Y |
DDL |
ROLLBACK |
Y |
N |
N |
ROLLBACK PREPARED |
Y |
N |
N |
SAVEPOINT |
Y |
N |
N |
SECURITY LABEL |
Y |
DDL |
|
SELECT INTO |
Y |
DDL |
|
SET |
Y |
N |
N |
SET CONSTRAINTS |
Y |
N |
N |
SHOW |
Y |
N |
N |
START TRANSACTION |
Y |
N |
N |
TRUNCATE TABLE |
Y |
||
UNLISTEN |
Y |
N |
N |
VACUUM |
Y |
N |
N |
ALTERシーケンス¶
一般にALTER SEQUENCE
がサポートされていますが、グローバルシーケンスを使用する場合、一部のオプションは効果がありません。
ALTER SEQUENCE ... RENAME
は、gallocシーケンスではサポートされていません(のみ)。
ALTER SEQUENCE ... SET SCHEMA
は、gallocシーケンスではサポートされていません(のみ)。
ALTERテーブル¶
一般に、 ALTER TABLE
コマンドは許可されています。ただし、いくつかのサブコマンドはサポートされていません。
ALTER TABLEは許可されないコマンド¶
ALTER TABLE
のいくつかのバリアントは現在、PGDノードでは許可されていません。
ADD COLUMN ... DEFAULT (non-immutable expression)—現在、異なるノードで異なるデータが得られるため、これは許可されません。推奨される回避策については、 列の追加 を参照してください。ADD CONSTRAINT ... EXCLUDE—除外制約は現在サポートされていません。除外制約は非同期システムではあまり意味がなく、再生できない変更につながります。ALTER TABLE ... SET WITH[OUT] OIDS—CREATE TABLEと同じ理由でサポートされていません。ALTER COLUMN ... SET STORAGE external—列がテーブルのレプリカIDの列の1つである場合、拒否されます。RENAME—自動パーティションテーブルの名前を変更することはできません。SET SCHEMA—自動パーティション分割テーブルのスキーマを設定できません。ALTER COLUMN ... TYPE—コマンドによってテーブル全体が書き換えられる場合、列の型の変更はサポートされていません。これは、変更がバイナリ強制ではない場合に発生します。バイナリ強制変更は、一方向にのみ許可される場合があります。たとえば、VARCHAR(128)からVARCHAR(256)への変更はバイナリ強制的であるため許可されますが、VARCHAR(256)からVARCHAR(128)への変更はバイナリ強制的ではないため、通常は許可されません。レプリケートされないALTER COLUMN ... TYPEは、列が新しい型に自動的にキャスト可能な場合に許可されます(USING句が含まれていません)。次に例を示します。テーブルの書き換えは、より大きなテーブルで長期間AccessExclusiveLockを保持するため、このようなコマンドは、いずれの場合も高可用性データベースでは実行できない可能性があります。推奨される回避策については、 列のタイプを変更する を参照してください。ALTER TABLE ... ADD FOREIGN KEY—現在のユーザーに参照先テーブルを読み取る権限がない場合、または参照先テーブルで現在のユーザーがバイパスできないRLS制限が有効になっている場合、 はサポートされません。
次の例は、 timestamp 型の定数値をtimestamptz
型の列に追加しようとするため失敗します。 timestamp
とtimestamptz
間のキャストは、セッションのタイムゾーンに依存するため、不変ではありません。
ALTER TABLE foo
ADD expiry_date timestamptz DEFAULT timestamp 2100-01-01 00:00:00 NOT NULL;
PGD 3.7.4以降、DMLロックを取得せずに、 CHECK および FOREIGN KEY
制約などの特定のタイプの制約を追加できます。ただし、これには、最初にNOT VALID
制約を作成し、次に ALTER TABLE ... VALIDATE CONSTRAINT
コマンドを使用して別のトランザクションで制約を検証するという2段階のプロセスが必要です。
CONSTRAINTの追加 を参照
詳細については。
ALTER TABLEロック¶
ALTER TABLE の次のバリアントは、
DDLロックのみを取得し、DMLロックは取得しません。
ALTER TABLE ... ADD COLUMN ... (immutable) DEFAULTALTER TABLE ... ALTER COLUMN ... SET DEFAULT expressionALTER TABLE ... ALTER COLUMN ... DROP DEFAULT書き換えが必要ない場合は
ALTER TABLE ... ALTER COLUMN ... TYPEALTER TABLE ... ALTER COLUMN ... SET STATISTICSALTER TABLE ... VALIDATE CONSTRAINTALTER TABLE ... ATTACH PARTITIONALTER TABLE ... DETACH PARTITIONALTER TABLE ... ENABLE TRIGGER(ENABLE REPLICA TRIGGERは引き続きDMLロックを取得します)ALTER TABLE ... CLUSTER ONALTER TABLE ... SET WITHOUT CLUSTERALTER TABLE ... SET ( storage_parameter = value [, ... ] )ALTER TABLE ... RESET ( storage_parameter = [, ... ] )ALTER TABLE ... OWNER TO
ALTER TABLE
の他のすべてのバリアントは、変更されるテーブルでDMLロックを取得します。
ALTER TABLE の一部のバリアントには、以下に示す制限があります。
ALTER TABLEの例¶
この次の例は、型の変更がバイナリ強制的であり、テーブルの書き換えを引き起こさないため、機能します。カタログのみの変更として実行されます。
CREATE TABLE foo (id BIGINT PRIMARY KEY, description VARCHAR(20));
ALTER TABLE foo ALTER COLUMN description TYPE VARCHAR(128);
ただし、 VARCHAR(128) からVARCHAR(20)
への変更はバイナリ強制ではないため、この変更を行ってコマンドを元に戻すことはできません。
ALTER TABLE foo ALTER COLUMN description TYPE VARCHAR(20);
回避策については、 制限付きDDL回避策 を参照してください。
一般およびレプリケートされない環境で可能なさまざまなタイプのALTER TABLE ... ALTER COLUMN TYPE
(ATCT)操作のコンテキストを提供すると役立ちます。
一部のATCT操作は、基になる列タイプのメタデータのみを更新し、基になるテーブルデータの書き換えを必要としません。これは通常、既存の列の型とターゲットの型がバイナリ強制型である場合に当てはまります。例:
CREATE TABLE sample (col1 BIGINT PRIMARY KEY, col2 VARCHAR(128), col3 INT);
ALTER TABLE sample ALTER COLUMN col2 TYPE VARCHAR(256);
バイナリ強制性のため、列の型をVARCHAR またはTEXT
データ型に変更することもできます。繰り返しますが、これは基になる列タイプのメタデータの更新にすぎません。
ALTER TABLE sample ALTER COLUMN col2 TYPE VARCHAR;
ALTER TABLE sample ALTER COLUMN col2 TYPE TEXT;
ただし、col2のサイズを減らしたい場合、それは基になるテーブルデータの書き換えにつながります。通常、テーブルの書き換えは制限されています。
ALTER TABLE sample ALTER COLUMN col2 TYPE VARCHAR(64);
ERROR: ALTER TABLE ... ALTER COLUMN TYPE that rewrites table data may not affect replicated tables on a PGD node
非テキスト型の例を示すには、INTEGER型の上記のcol3を検討してください。 SMALLINTまたはBIGINTに変換しようとするATCT操作は、上記と同様の方法で失敗します。
ALTER TABLE sample ALTER COLUMN col3 TYPE bigint;
ERROR: ALTER TABLE ... ALTER COLUMN TYPE that rewrites table data may not affect replicated tables on a PGD node
これらの両方の失敗したケースでは、現在の型からターゲット型への自動割り当てキャストがあります。ただし、バイナリ強制性はなく、基になるテーブルデータの書き換えが発生します。
このような場合、制御されたDBA環境では、すべてのノードの非レプリケート環境でこの列の型のローリングアップグレードを1つずつ採用することにより、列の型を自動的にキャスト可能なものに変更できます。 DDLがレプリケートされず、列の型が自動的にキャスト可能なものに変更されたとします。次に、変更を実行しているノードでローカルに書き換えを許可し、この同じテーブルの他のノードでの同時アクティビティを許可できます。次に、すべてのノードでこのレプリケートされないATCT操作を1つずつ繰り返して、 EDB Postgres分散クラスター全体で列タイプの目的の変更をもたらすことができます。これには書き換えが含まれるため、アクティビティは引き続き短期間DMLロックを取得するため、クラスター全体が使用可能である必要があります。これらの詳細が整ったら、次のようにレプリケートされない変更アクティビティのローリングアップグレードを実行できます。
- - foreach node in EDB Postgres Distributed cluster do:
SET bdr.ddl_replication TO FALSE;
ALTER TABLE sample ALTER COLUMN col2 TYPE VARCHAR(64);
ALTER TABLE sample ALTER COLUMN col3 TYPE BIGINT;
RESET bdr.ddl_replication;
- - done
多くのデータ型で自動割り当てキャストを使用できるため、このローカルのレプリケートされないATCT操作は、さまざまな変換をサポートします。また、
USING
句を使用するATCT操作は、自動割り当てキャストがないため失敗する可能性があります。この例は、自動割り当てキャストを使用したいくつかの一般的な変換を示しています。
- - foreach node in EDB Postgres Distributed cluster do:
SET bdr.ddl_replication TO FALSE;
ATCT operations to-from {INTEGER, SMALLINT, BIGINT}
ATCT operations to-from {CHAR(n), VARCHAR(n), VARCHAR, TEXT}
ATCT operations from numeric types to text types
RESET bdr.ddl_replication;
- - done
この例は、レプリケートされない環境で許可される可能性のあるATCT操作の完全なリストではありません。すべてのATCT操作が機能するわけではありません。 DDLレプリケーションを無効にしても、自動割り当てをできない場合は失敗します。したがって、数値型からテキスト型への変換はレプリケートされない環境では機能しますが、テキスト型から数値型への変換は失敗します。
SET bdr.ddl_replication TO FALSE;
- - conversion from BIGINT to TEXT works
ALTER TABLE sample ALTER COLUMN col3 TYPE TEXT;
- - conversion from TEXT back to BIGINT fails
ALTER TABLE sample ALTER COLUMN col3 TYPE BIGINT;
ERROR: ALTER TABLE ... ALTER COLUMN TYPE which cannot be automatically cast to new type may not affect replicated tables on a PGD node
RESET bdr.ddl_replication;
レプリケートされない環境でのATCT操作はさまざまな型変換をサポートしていますが、基になるテーブルデータに新しいデータ型に割り当てることができない値が含まれている場合、書き換えが失敗する可能性があります。たとえば、列の現在の型がVARCHAR(256)
であり、レプリケートされないATCT操作を試行してVARCHAR(128)
に変換するとします。テーブルに128バイトを超える既存のデータがある場合、書き換え操作はローカルで失敗します。
INSERT INTO sample VALUES (1, repeat(a, 200), 10);
SET bdr.ddl_replication TO FALSE;
ALTER TABLE sample ALTER COLUMN col2 TYPE VARCHAR(128);
INFO: in rewrite
ERROR: value too long for type character varying(128)
基になるテーブルのデータが新しい型の特性を満たしている場合、書き換えは成功します。ただし、レプリケートされないローリングデータ型のアップグレードをまだ実行していない他のノードが128バイトを超える新しいデータをこのローカルATCT操作に同時に導入した場合、レプリケーションは失敗する可能性があります。これにより、クラスター内のレプリケーションが停止します。したがって、これらのレプリケートされないローリングデータ型アップグレード操作を実行するときは、データベースおよびアプリケーションレベルでのデータ型の制限と特性に注意してください。このようなATCT操作を、制御され完全に認識したDBA環境で実行およびテストすることを強くお勧めします。これらのATCT操作は非対称であり、失敗した特定の変更をバックアウトすると、テーブルの書き換えに時間がかかる場合があります。
また、トランザクションブロックで暗黙的なキャスト可能なALTERアクティビティを実行することはできません。
ALTERタイプ¶
ALTER TYPE
は複製されますが、PostgreSQLはこれらの依存関係を記録しないため、そのデータ型を使用するすべてのテーブルにグローバルDMLロックが適用されるわけではありません。
制限付きDDL回避策 を参照してください。
コメント¶
COMMENT ON のすべてのバリアントが許可されますが、
COMMENT ON TABLESPACE/DATABASE/LARGE OBJECT は複製されません。
CREATE PROFILEまたはALTER PROFILE¶
機能がSECURITY DEFINER
の場合、プロファイルに関連付けられたPASSWORD_VERIFY_FUNCTION
はIMMUTABLE でなければなりません。このようなCREATE PROFILE
またはALTER PROFILE
コマンドは複製されますが、このプロファイルを使用する後続のCREATE USER
またはALTER USER コマンドは、writer
ワーカーがエラー:cannot change current role within security-restricted operation
をスローしたため、レプリケーションを中断します。
シーケンスを作成する¶
一般にCREATE SEQUENCE
がサポートされていますが、グローバルシーケンスを使用する場合、一部のオプションは効果がありません。
テーブルを作成する¶
一般に、 CREATE TABLE はサポートされていますが、
CREATE TABLE WITH OIDS はPGDノードでは許可されていません。
CREATE TABLE ASとSELECT INTO¶
CREATE TABLE AS およびSELECT INTO
は、すべてのサブコマンドも許可される場合にのみ許可されます。
説明する¶
通常、 EXPLAIN は許可されますが、 EXPLAIN ANALYZE
はデータベースに副作用を与える可能性があるため、いくつかの制限があります。
EXPLAIN ANALYZEレプリケーション¶
EXPLAIN ANALYZE は、分析されたステートメントの複製ルールに従います。
EXPLAIN ANALYZEロック¶
EXPLAIN ANALYZE
は、分析されたステートメントのロックルールに従います。
GRANTとREVOKE¶
一般に、 GRANT およびREVOKE
ステートメントはサポートされていますが、
GRANT/REVOKE ON TABLESPACE/LARGE OBJECT は複製されません。
ロックテーブル¶
LOCK TABLEは複製されませんが、 bdr.lock_table_locking がon
に設定されている場合、グローバルDMLロックを取得する場合があります。
bdr.global_lock_table()
ファンクションを使用して、グローバルDMLロックを明示的に要求することもできます。
セキュリティラベル¶
SECURITY LABEL のすべてのバリアントが許可されますが、
SECURITY LABEL ON TABLESPACE/DATABASE/LARGE OBJECT
は複製されません。
TRUNCATEレプリケーション¶
TRUNCATE コマンドは、
DDLステートメントとしてではなく、DMLとしてレプリケートされます。テーブルのTRUNCATE
がレプリケートされるかどうかは、影響を受ける各テーブルのレプリケーション設定によって異なります。
TRUNCATEロック¶
TRUNCATE は他のDDLと同じように複製されませんが、
bdr.truncate_locking が on
に設定されていると、グローバルDMLロックを取得できます。
ロール操作ステートメント¶
ユーザーはPostgreSQLインスタンスのグローバルオブジェクトです。つまり、PGDは個々のデータベースレベルで動作しますが、ユーザーは複数のデータベースにまたがります。これは、ロール操作ステートメントの処理には特別な配慮が必要であることを意味します。
PGDでは、レプリケートされたDDLによって参照されるロールがすべてのノードに存在する必要があります。ロールは、同じ付与、パスワードなどを持つ必要はありませんが、存在している必要があります。
bdr.role_replication
が有効になっている場合(デフォルト)、PGDはロール操作ステートメントをレプリケートし、ロール操作ステートメントがPGD対応データベースで実行されます。
ロール操作ステートメントには次のものが含まれます。
CREATE ROLEALTER ROLEDROP ROLEGRANT ROLECREATE USERALTER USERDROP USERCREATE GROUPALTER GROUPDROP GROUP
一般に、次のいずれかです。
bdr.role_replication = offでシステムを構成し、Ansible、Puppet、Chefなどの外部オーケストレーションツールで、またはbdr.replicate_ddl_command(...)によって明示的に複製されたすべてのロールの変更(ユーザーとグループ)を展開します。PostgreSQLインスタンス上のちょうど1つのPGD対応データベースが
bdr.role_replication = onを持つようにシステムを構成し、そのデータベースですべてのロール管理DDLを実行します。
すべてのロール管理コマンドを1つのデータベースで実行することをお勧めします。
ロールのレプリケーションがオフになっている場合、管理者は、1つのノードでDDLが使用するロールが他のノードにも存在することを確認する必要があります。そうしないと、他のノードでロールが作成されるまで、PGD applyはエラーでストールします。
注釈
PGDは、PGD対応のPostgreSQLインスタンス内のPGD非対応のデータベースで実行される場合、ロール管理ステートメントをキャプチャおよびレプリケートしません。たとえば、DB 'bdrdb'(bdrグループメンバー)と'postgres'(ベアdb)、および`bdr.role_replication = on` がある場合、 bdrdb で実行される`CREATE USER` は複製されますが、 postgres で実行される`CREATE USER` は複製されません。
制限付きDDL回避策¶
PGD DDL操作処理の制限の一部を回避できます。多くの場合、操作を小さな変更に分割すると、単一のステートメントとして許可されないか、過度のロックが必要な目的の結果が生成される可能性があります。
CONSTRAINTの追加¶
DMLロックを必要とせずに CHECK および FOREIGN KEY
制約を追加できます。これには2段階のプロセスが含まれます。
ALTER TABLE ... ADD CONSTRAINT ... NOT VALIDALTER TABLE ... VALIDATE CONSTRAINT
2つの異なるトランザクションでこれらの手順を実行します。これらの手順はどちらもテーブルでのみDDLロックを取得するため、1つ以上のノードがダウンしている場合でも実行できます。ただし、制約を検証するには、PGDで次のことを保証する必要があります。
クラスター内のすべてのノードは
ADD CONSTRAINTコマンドを参照します。制約が適用されたレプリケーションを検証するノードは、それらのノードにNOT VALID制約を作成する前に、他のすべてのノードからの変更を行います。
そのため、新しいメカニズムでは制約の検証中にすべてのノードを稼働させる必要はありませんが、すべてのノードがALTER TABLE .. ADD CONSTRAINT ... NOT VALID
コマンドを適用し、十分に進行したことは引き続き必要です。
PGDは、制約を検証する前に、一貫した状態に到達するのを待ちます。
新しい機能では、クラスターがRaftプロトコルバージョン24以降で実行される必要があります。 Raftプロトコルがまだアップグレードされていない場合、古いメカニズムが使用され、DMLロック要求が発生します。
列の追加¶
揮発性のデフォルトを持つ列を追加するには、別のトランザクションで次のコマンドを実行します。
ALTER TABLE mytable ADD COLUMN newcolumn coltype; -- Note the lack of DEFAULT or NOT NULL
ALTER TABLE mytable ALTER COLUMN newcolumn DEFAULT volatile-expression;
BEGIN;
SELECT bdr.global_lock_table(mytable);
UPDATE mytable SET newcolumn = default-expression;
COMMIT;
このアプローチは、スキーマの変更と行の変更を個別のトランザクションに分割し、PGDが実行できるため、PGDグループ内のすべてのノードで一貫したデータが得られます。
最良の結果を得るには、更新をチャンクにバッチにして、一度に数万または数十万を超える行を更新しないようにします。埋め込みトランザクションでPROCEDURE
を使用してこれを行うことができます。
変更の最後のバッチは、テーブルでグローバルDMLロックを取得するトランザクションで実行する必要があります。そうしないと、他のノードのテーブルに同時に挿入される行を見落とす可能性があります。
必要に応じて、 UPDATE
が終了した後にALTER TABLE mytable ALTER COLUMN newcolumn NOT NULL;
を実行できます。
列のタイプを変更する¶
列の型を変更すると、PostgreSQLがテーブルを書き換える可能性があります。場合によっては、この書き換えを回避できます。例:
CREATE TABLE foo (id BIGINT PRIMARY KEY, description VARCHAR(128));
ALTER TABLE foo ALTER COLUMN description TYPE VARCHAR(20);
このステートメントを書き換えて、制限をデータ型の変更ではなくテーブル制約にすることにより、テーブルの書き換えを回避できます。必要に応じて、後続のコマンドで制約を検証して、長いロックを回避できます。
CREATE TABLE foo (id BIGINT PRIMARY KEY, description VARCHAR(128));
ALTER TABLE foo
ALTER COLUMN description TYPE varchar,
ADD CONSTRAINT description_length_limit CHECK (length(description) <= 20) NOT VALID;
ALTER TABLE foo VALIDATE CONSTRAINT description_length_limit;
検証が失敗した場合、失敗した行だけをUPDATE できます。 length()
を使用してTEXT およびVARCHAR 、またはscale()
を使用してNUMERIC データ型でこの手法を使用できます。
列の種類を変更する一般的な場合、最初に目的の種類の列を追加します。
ALTER TABLE mytable ADD COLUMN newcolumn newtype;
BEFORE INSERT OR UPDATE ON mytable FOR EACH ROW ..
として定義されるトリガーを作成します。これはNEW.newcolumn
をNEW.oldcolumn
に割り当て、テーブルへの新しい書き込みで新しい列が自動的に更新されるようにします。
テーブルをバッチでUPDATE
、埋め込みトランザクションでPROCEDURE を使用してoldcolumn
の値をnewcolumn
にコピーします。作業をバッチ処理すると、大きなテーブルの場合、レプリケーションのラグを減らすことができます。
IDの範囲または任意の方法で更新しても問題ありません。または、小さなテーブルの場合、テーブル全体を1回のパスで更新できます。
CREATE INDEX ...
新しい列に必要なインデックス。ロック期間を短縮するために、各ノードでDDLレプリケーションなしでCREATE INDEX ... CONCURRENTLY
実行を個別に使用しても安全です。
ALTER NOT NULL およびCHECK
制約を追加する列、必要に応じて。
BEGINトランザクション。
1.追加したトリガーをDROP します。
ALTER TABLEを使用して、列に必要なDEFAULTを追加します。
1.古い列をDROP 。
ALTER TABLE mytable RENAME COLUMN newcolumn TO oldcolumn。COMMIT。
注釈
列を削除するため、テーブルに依存するビュー、プロシージャなどの再作成が必要になる場合があります。列を`CASCADE` ドロップする場合は注意してください。それを参照していたものをすべて再作成する必要があるためです。
他のタイプの変更¶
ALTER TYPE
ステートメントは複製されますが、影響を受けるテーブルはロックされません。
このDDLを使用する場合は、新しいタイプを使用する前に、ステートメントがすべてのノードで正常に実行されたことを確認してください。
bdr.wait_slot_confirm_lsn() 関数を使用してこれを実現できます。
この例では、DMLステートメントで新しい値を使用する前に、 DDLがすべてのノードに書き込まれるようにします。
ALTER TYPE contact_method ADD VALUE email;
SELECT bdr.wait_slot_confirm_lsn(NULL, NULL);
DDLのように動作するPGD関数¶
次のPGD管理関数は、 DDLのように機能します。これは、 DDLレプリケーションがアクティブであり、 DDLフィルター設定で許可されている場合、グローバルロックを取得しようとし、アクションがレプリケートされることを意味します。詳細については、個々の機能の文書を参照してください。
レプリケーションセット管理
bdr.create_replication_setbdr.alter_replication_setbdr.drop_replication_setbdr.replication_set_add_tablebdr.replication_set_remove_tablebdr.replication_set_add_ddl_filterbdr.replication_set_remove_ddl_filter
コンフリクトマネジメント
bdr.alter_table_conflict_detectionbdr.column_timestamps_enablebdr.column_timestamps_disable
シーケンス管理
bdr.alter_sequence_set_kind
ストリームトリガー
bdr.create_conflict_triggerbdr.create_transform_triggerbdr.drop_trigger