DDL Replication¶
DDLは「Data Definition Language」の略です。データベースオブジェクトを作成、変更、および削除するSQL言語のサブセット。
操作の利便性と正確さのために、 BDRはほとんどのDDLアクションをレプリケートしますが、次の例外があります。
一時的またはログされていないリレーション
特定の、主に長時間実行さDDLステートメント(以下のリストを参照)
ロックコマンド(LOCK)
テーブルメンテナンスコマンド(VACUUM、 ANALYZE、CLUSTER、REINDEX)
オートバキュームのアクション
・操作コマンド(CHECKPOINT、ALTER SYSTEM)
データベースまたはテーブルスペースに関するアクション
自動DDLレプリケーションにより、 DDL変更をすべてのノードに手動で配布して一貫性を保証ことなく、特定のDDL変更を簡単にmakeことができます。
デフォルトのレプリケーションセットでは、 DDLはデフォルトですべてのノードに複製されます。 DDLをレプリケートするには、 DDLレプリケーションフィルターをレプリケーションセットに追加する必要があります。
DDLレプリケーションのフィルタリング を参照してください。
BDRは、 DDLレプリケーションに関してはスタンドアロンのPostgreSQLとは大きく異なり、同じように扱うことがBDRの最も一般的な操作上の問題です。
テーブルレプリケーションとの主な違いは、 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;
設定makeと、 BDRは実行されたDDLコマンドのグローバルロックとレプリケーションの両方をスキップするため、すべてのノードでDDLを手動で実行する必要があります。
警告
グローバルロックを使用せずに各ノードでDDLを手動で実行すると、競合するDDLまたはDMLが同時に実行されている場合にBDRグループ全体がレプリケーションを停止する場合があります。
bdr.ddl_replication パラメータは、
bdr_superuser、スーパーユーザ、または構成ファイルでのみ設定できます。
BDRシステムでのDDLの実行¶
BDRグループは、スタンドアロンのPostgreSQLサーバと同じではありません。これは、集中ロックやトランザクションコーディネーターのない非同期マルチマスターレプリケーションに基づいています。これは、 DDLの実行時に重要な意味を持ちます。
並列実行されるDDLは、 BDRで引き続き実行されます。 DDLの実行は、実行時に各ノードでのパラレルオペレーションに影響を与えるパラメーターを尊重するため、ノード間の設定の違いが目立つ場合があります。
競合するDDLの実行を防ぐニーズがあります。 そうしないと、 DDLレプリケーションでエラーが発生し、レプリケーションが停止します。
BDRは、これらの問題に対して3つのレベルの保護を提供します。
ddl_locking = 'dml'
は、一度に1つのノードからのみDDLを実行場合に使用可能な操作に最適なオプションです。これはデフォルトではありませんが、
DDLの実行元を制御できる場合は、この設定を使用して、ノード間の競合がないように保証ことをお勧めします。ノード内の競合は既にPostgreSQLによって処理されています。
ddl_locking = on は最も厳密なオプションであり、
DDLが任意のノードから同時に実行される可能性があり、正確性を保証したい場合に最適です。
ddl_locking = off
は最も厳密でないオプションであり、一般的な使用では危険です。このオプションはロックを完全にスキップするため、パフォーマンスのオーバーヘッドが回避されるため、新しい空のデータベーススキーマを作成するときに役立ちます。
これらのオプションは、 bdr_superuser、スーパーユーザ、または構成ファイルでのみ設定できます。
bdr.replicate_ddl_command
を使用する場合、そのファンクションに渡されたDDLコマンドに対してのみ指定されたbdr.ddl_locking
設定を使用して、3番目の引数を介してこのパラメータを直接設定できます。
DDLロックの詳細¶
BDRでレプリケートされたDDLの正確性を強制するために使用される2種類のロックがあります。
最初の種類はグローバルDDLロックと呼ばれ、 ddl_locking = on
の場合にのみ使用されます。グローバルDDLロックは、各DDLステートメントの実行中にクラスターで他のDDLが実行されるのを防ぎます。これにより、一般的なケースでは完全な正確さが保証されますが、多くのシンプルケースには明らかに厳しすぎます。
BDRは、スキーマが変更されるトランザクションで初めてDDL操作のグローバルロックを取得します。これにより、クラスター内のDDL実行トランザクションが効果的にシリアル化されます。言い換えれば、
DDLの実行中は、 別のテーブルに影響を与えたとしても
、ノード上の他の接続は別のDDLコマンドを実行できません。
DDL操作のロックを取得するには、 DDLを実行するBDRノードがBDRグループ内の他のノードに接続し、 DDLを実行排他的権限を付与するように要求します。ロック要求は通常のレプリケーションストリームを介して送信され、ノードもレプリケーションストリームを介して応答します。したがって、ノード(または少なくとも大部分のノード)がレプリケーションの遅延をあまり発生せずに実行されていることが重要です。そうしないと、ノードがDDLロックを取得するまでに非常に時間がかかる場合があります。過半数のノードが同意すると、 DDLの実行が実行されます。
DDLロックの順序付けは、 Raftプロトコルを使用して決定されます。 1つのノードで実行されるDDLステートメントは、他のすべてのノードで同じシーケンスで実行されます。
DDLを実行しているノードがクラスターで実行された以前のすべてのDDLの効果を保証オーダーに、以前のDDLを実行したノードに追いつくまで待機します。現在のDDLを実行しているノードが以前のDDLを実行したノードに対してレプリケーションが遅れている場合、ロックの取得に非常に時間がかかります。したがって、単一のノード、または他のノードで発生したレプリケーションの変更にほぼ追いついたノードからDDLを実行することをお勧めします。
2 番目の種類は、リレーション DML ロックと呼ばれます。この種のロックは、 制約または一意性制約のいずれ検査制約で使用され、 DDLステートメントにより、実行中のDMLステートメントが失敗する可能性があり制約。リレーションDMLロックは、一度に1つのリレーションにのみ影響します。リレーションDMLロックにより、レプリケーションがエラーで停止保証可能性のある変更がキューにある間はDDLが実行されません。
テーブルでグローバルDMLロックを取得するには、 DDLを実行しているBDRノードがBDRグループ内の他のすべてのノードに接続し、書き込みに対してテーブルをロックするように要求し、そのテーブルへの保留中の変更がすべて排出されるまで待機します。すべてのノードが完全に追いつくと、DMLロックの発信者はフリーにテーブルのスキーマ変更を実行し、他のノードにレプリケートできます。
グローバルDMLロックは各ノードのテーブルに EXCLUSIVE LOCK を保持するため、実行中にそのテーブルに対するDML、他のDDL、VACUUM、およびインデックスコマンドをブロックすることに注意してください。これは、通常は EXCLUSIVE LOCK以上をとらないコマンドに対してグローバルDMLロックが保持されている場合でも当てはまります。
保留中のDML操作が排出されるのを待機すると、時間がかかる場合があります。レプリケーションが現在遅れている場合。これは、データの変更とは異なり、行の表現形式とコンストレインに影響を与えるスキーマの変更は、構成されたすべてのノードに到達可能で、現在の書き込みレートに十分対応している場合にのみ実行できることを意味します。このようなDDLコマンドをノードのダウン中に実行する必要がある場合は、最初にダウンしたノードを構成から削除する必要があります。
DDLステートメントがレプリケートされない場合、グローバルロックは取得されません。
BDRシステムでのDDLの実行 で説明されているように、ロックの動作は
bdr.ddl_locking
パラメータで指定されます。
ddl_locking = onはグローバルDDLロックを取得し、必要に応じてリレーションDMLロックを取得します。ddl_locking = dmlはグローバルDDLロックをスキップし、必要に応じてリレーションDMLロックを取得します。ddl_locking = offは、グローバルDDLロックとリレーションDMLロックの両方をスキップします。
また、一部のBDRファンクションはDDLを変更するため、これらのファンクションにはDDLロックの動作が適用されることに注意してください。これは、各ファンクションのドキュメントに記載されています。
したがって、 ddl_locking = dml
は、競合するDDLが他のノードから実行されないことが保証できる場合にのみ安全です。この設定では、グローバルDDLロックのみを必要とするステートメントはグローバルロックをまったく使用しません。
ddl_locking = off は、
DDLを実行データベースオブジェクトに競合するDDLがないこと、および競合するDML操作がないことをユーザが保証できる場合にのみ安全です。ロックをオフにして問題が発生した場合、データへの進行中の変更が失われる可能性があります。発生した問題は、ユーザアプリケーションチームが解決する必要があります。
場合によっては、同時に実行されるDDLを適切にシリアル化できます。これらのシリアル化エラーが発生した場合、 DDLが再実行される場合があります。
DDLレプリケーションは、昇格するまでロジカルスタンバイノードでアクティブになりません。
- 一部のBDR管理レプリケーションはDDLのように機能することに注意してDDL。レプリケートされた関数の完全なリストは、
DDLのように動作するBDRFunctions にリストされています。
一時テーブルで実行されるDDLは、グローバルロックを必要としません。
現在のトランザクションで作成されたオブジェクトのALTERまたはDROPには、グローバルDMLロックは必要ありません。
グローバルDDLロックとグローバルDMLロックのモニタリングは、 モニタリングとロギング の章に示されています。
DDLの影響の最小化¶
任意のデータベースに対する優れた運用上のアドバイス、これらの点はBDRではさらに重要になります。
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までのバージョンで複製されますが、 BDR 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がシステムを長時間停止している場合、他のステートメントをキャンセルするのと同じように、元のノードでDDLをキャンセルできます。たとえば、
psql またはpg_cancel_backend()
を使用します。他のノードからDDLロックをキャンセルすることはできません。
(オプショナル)グローバルロックのタイムアウト設定で、グローバルロックにかかる時間を制御できます。
bdr.global_lock_timeout
は、グローバルロックを取得するための待機がキャンセルされるまでにかかる時間を制限します。
bdr.global_lock_statement_timeout
は、グローバルロックを保持するトランザクション内のステートメントのランタイム長さを制限し、
bdr.global_lock_idle_timeout
は、グローバルロックを保持するトランザクションの最大許容アイドル時間(ステートメント間の時間)を設定します。これらのタイムアウトはすべて、値をゼロに設定することで無効にできます。
送信元ノードでDDLオペレーションがコミットされると、キャンセルまたは中止できません。 BDRグループは、グローバルロックを確認した他のノードに正常に適用され、リプレイが確認されるまで待機する必要があります。これが、 DDLトランザクションを短く高速に保つことが重要である理由です。
ダウンノードでのDDLの処理¶
グローバルDDLロックを開始したノードがグローバルロック( DDLまたはDML)を取得した後にダウンした場合、ロックはアクティブなままです。タイムアウトが設定されている場合でも、グローバルロックはタイムアウトしません。ノードが復旧すると、保持しているすべてのグローバルロックを自動的にリリースします。
長期間(または永久に)ダウンしたままの場合は、グローバルロックをリリースするオーダーにノードをBDRグループから削除します。これが、
SET コマンドをbdr_superuser として使用して緊急DDLを実行し、
bdr.ddl_locking の値を更新する理由の1つかもしれません。
グローバルロックを確認した後、それを取得ロックコマンドが実行される前に他のノードの1つがダウンした場合、
前のセクションで述べたように、グローバルDDLロックはノードの過半数のみが応答する必要があるため、クラスターのパートがダウンしても、マジョリティが実行されていて到達可能である限りロックします。クラスター全体が使用可能な場合を除きます。
グローバルDDLまたはグローバルDMLロックがあるときに別のノードがダウンした場合、コマンドは正常に続行され、ロックが解放されます。
ステートメント固有のDDLレプリケーションに関する懸念¶
すべてのコマンドを自動的に複製できるわけではありません。このようなコマンドは、
bdr.ddl_replication
をオフにしてDDLレプリケーションをオフにしない限り、通常は許可されません。
- BDRは、データベースでアクティブなときに一部のDDLステートメントの実行を防ぎます。これにより、正しくレプリケートできないステートメント、またはレプリケーションがまだサポートされていないステートメントを禁止することにより、システムの一貫性が保護されます。いくつかの制限付きでサポートされているステートメントについては、
DDL Statements With Restrictions で説明されています。
BDRで完全に許可されないコマンドは、禁止されているDDLステートメントで説明されています。
BDRでステートメントが許可されていない場合、多くの場合、同じことを行う別の方法を見つけることができます。例、
volatileのデフォルト値で列を追加するALTER TABLE
を実行することはできませんが、一般的には、動作するシリーズの独立したALTER TABLE
およびUPDATE ステートメントとして言い換えることができます。
通常、サポートされていないステートメントは実行されず、
feature_not_supported (SQLSTATE 0A000 ) エラーが発生します。
一時オブジェクトを参照または依存するDDLはBDRでレプリケートできず、 DDLレプリケーションを有効にして実行するとエラーがスローされることに注意してください。
BDR 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 |
DDL |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
Y |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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 |
DDL |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
Y |
DDL |
CREATE SERVER |
Y |
Y |
DDL |
CREATE STATISTICS |
Y |
Y |
DDL |
CREATE SUBSCRIPTION |
Y |
Y |
DDL |
CREATE SYNONYM |
Y |
Y |
DDL |
CREATE TABLE |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
Y |
DDL |
CREATE TABLE AS |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
FETCH |
Y |
N |
N |
GRANT |
Y |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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 |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
DDL |
REVOKE ROLE |
Y |
Y |
DDL |
ROLLBACK |
Y |
N |
N |
ROLLBACK PREPARED |
Y |
N |
N |
SAVEPOINT |
Y |
N |
N |
SECURITY LABEL |
Y |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
DDL |
SELECT INTO |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
Y |
DDL |
SET |
Y |
N |
N |
SET CONSTRAINTS |
Y |
N |
N |
SHOW |
Y |
N |
N |
START TRANSACTION |
Y |
N |
N |
TRUNCATE TABLE |
Y |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
:ref:``bdr.global_consensus_journal_details`<bdr.global_consensus_journal_details>` |
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
の一部のバリアントは、現在BDRノードでは許可されていません。
ADD COLUMN ... DEFAULT (non-immutable expression)- 現在、異なるノードで異なるデータが得られるため、これは許可されません。推奨される回避策については、列の追加 を参照してください。
ADD CONSTRAINT ... EXCLUDE- 除外コンストレインは現在サポートされていません。除外コンストレインは非同期システムではあまり意味がなく、再生できない変更につながります。ALTER TABLE ... SET WITH[OUT] OIDS-CREATE TABLEと同じ理由でサポートされていません。ALTER COLUMN ... SET STORAGE external- 列がテーブルのレプリカアイデンティティの列の場合、拒否されます。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;
BDR 3.7.4以降、 CHECK および FOREIGN
KEYコンストレインなどの特定のタイプのコンストレインは、DMLロックを取得せずに追加できます。ただし、これには、最初に
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);
推奨される回避策については、後述を参照してください。
一般および非レプリケート環境で可能なさまざまなタイプの 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 BDR 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 BDR node
上記の両方の失敗したケースでは、現在の型からターゲット型への自動代入キャストが存在します。ただし、バイナリ強制はなく、基になるテーブルデータの書き換えが発生します。
このような場合、制御されたDBA環境では、すべてのノードの非レプリケート環境でこの列の型のローリングアップグレードを1つずつ採用することにより、列の型を自動的にキャスト可能なものに変更できます。 。 DDLがレプリケートされず、列型が上記のように自動的にキャスト可能なものに変更される場合、この同じテーブルの他のノードでの同時アクティビティとともに、変更を実行するノードでローカルに書き換えを許可できます。このレプリケートされないATCTオペレーションをすべてのノードで1つずつ繰り返すことで、 BDRクラスター全体で列タイプを必要に応じて変更できます。これには書き換えが含まれるため、アクティビティは短期間でもDMLロックを取得するため、クラスター全体が使用可能である必要があることに注意してください。上記の詳細を設定したら、レプリケートされない変更アクティビティのローリングアップグレードを以下のように実行できます。
- - foreach node in BDR 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 BDR 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 BDR 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)
基になるテーブルデータが新しい型の特性を満たしている場合、書き換えは成功します。ただし、他のノード(レプリケートされないローリングデータタイプのアップグレードをまだ実行していない)がこのローカルATCTオペレーションに同時に128バイトを超える新しいデータを導入した場合、レプリケーションが失敗する可能性があります。これにより、クラスターでのレプリケーションが停止します。したがって、これらのレプリケートされないローリングデータタイプアップグレード操作を実行するときは、データベースおよびアプリケーションレベルでのデータタイプの制限と特性に注意することが重要です。このようなATCT操作は、制御された完全に認識されたDBA環境で実行およびテストすることを 強く お勧めします。これらのATCT操作は非対称であり、失敗した特定の変更をバックアウトすると、テーブルの書き換えが長時間続く可能性があることに注意する必要があります。
また、上記の暗黙的なキャスト可能なALTERアクティビティはトランザクションブロックでは実行できないことにノートしてください。
ALTERタイプ¶
ノートは複製されロックが、 PostgreSQLはこれらの依存関係をレコードしないため、そのデータタイプを使用するすべてのテーブルに適用されないことに注意してください。以下の回避策を参照してください。
コメント¶
COMMENT ONのすべてのバリアントが許可されますが、
COMMENT ON TABLESPACE/DATABASE/LARGE OBJECT は複製されません。
シーケンスを作成する¶
通常、 CREATE SEQUENCE
がサポートされていますが、グローバルシーケンスを使用する場合、一部のオプションは効果がありません。
テーブルを作成する¶
通常、 CREATE TABLE はサポートされていますが、
BDRノードではCREATE TABLE WITH OIDS は許可されていません。
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 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インスタンスのグローバルオブジェクト。つまり、 BDRは個々のデータベースレベルで動作しマルチプル。これは、ロール操作ステートメントのハンドリングには追加の考慮がニーズであることを意味します。
BDRでは、レプリケートされたDDLによって被参照されるロールがすべてのノードに存在する必要があります。ロールは、同じ付与、パスワードなどを持つ必要はありませんが、存在する必要があります。
BDRが有効になっ操作ロール場合(デフォルト)、 BDR対応データベースでロール操作ステートメントが実行されます。
ロール操作ステートメントには、次のステートメントが含まれます。
ロールを作成する
ALTER ROLE
ドロップロール
グラントロール
ユーザーを作成
ALTER USER
DROP USER
グループを作成
ALTERグループ
ドロップグループ
一般に、次のいずれかです。
システムは
bdr.role_replication = offで構成する必要があり、すべてのロール(ユーザとグループ)の変更は、Ansible、Puppet、Chefなどの外部オーケストレーションツールで展開するか、bdr.replicate_ddl_command(...)を介して明示的に複製する必要があります。またはPostgreSQLインスタンス上の1つのBDR対応データベースに
bdr.role_replication = onがあり、すべてのロール管理DDLがそのデータベースで実行されるように、システムを構成する必要があります。
すべてのロール管理コマンドは 1 つのデータベース内で実行することを強くお勧めします。
ロールのレプリケーションがオフになっている場合、管理者は、1つのノードでDDLが使用するロールが他のノードにも存在することを保証必要があります。そうでない場合、他のノードでロールが作成されるまでBDR
applyはERROR で停止します。
注: BDRは、
BDR対応のPostgreSQLインスタンス内のBDR非対応のデータベースで実行された場合、ロール管理ステートメントをキャプチャおよび複製しません。例、
DB ‘bdrdb’(bdr group メンバ)と’postgres’(bare
db)、およびbdr.role_replication = on がある場合、 bdrdb
で実行されるCREATE USER は複製されますが、 postgres
で実行されるCREATE USER は複製されません。
制限されDDLの回避策¶
BDR DDLオペレーションハンドリングの制限の一部は回避できます。多くの場合、オペレーションを小さな変更に分割すると、単一のステートメントとして許可されないか、過度のロックが必要な結果が生成される場合があります。
CONSTRAINTの追加¶
CHECKおよびFOREIGN KEY制約は、DMLロックを必要とせずに追加できます。これには2段階のプロセスが必要です。
ALTER TABLE ... ADD CONSTRAINT ... NOT VALIDALTER TABLE ... VALIDATE CONSTRAINT
これらの手順は、2つの異なるトランザクションで実行する必要があります。これらの手順はどちらもテーブルのDDLロックのみを取得するため、1つ以上のノードがダウンしている場合でも実行できます。ただし、制約を検証するオーダーには、
BDRは、クラスター内のすべてのノードがADD CONSTRAINT
コマンドを認識し、制約を検証するノードが他のすべてのノードからのレプリケーション変更を適用したことを保証必要がありますそれらのノードに制約を作成します。したがって、新しいメカニズムでは制約の検証中にすべてのノードを稼働させる必要はありませんが、すべてのノードが
ALTER TABLE .. ADD CONSTRAINT ... NOT VALID
コマンドを適用して十分に進行している必要があります。
BDRは、制約を検証する前に一貫した状態に到達するのを待ちます。
新しい機能では、クラスターがRaftプロトコルバージョン24以降で実行される必要があることに注意してください。 Raftプロトコルがまだアップグレードされていない場合、古いメカニズムが使用され、DMLロック要求が発生します。
列の追加¶
volatile デフォルトを使用して列を追加するには、別のトランザクションで次のコマンドを実行します。
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;
これにより、スキーマの変更と行の変更がBDRで実行できる個別のトランザクションに分割され、 BDRグループ内のすべてのノードで一貫したデータが得られます。
最良の結果を得るには、更新をバッチにまとめて、一度に数万または数十万を超える行を更新しないようにします。これは、トランザクションが埋め込みた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のレンジまたは好みのメソッドで更新するか、小さなテーブルの場合はテーブル全体を一度に更新します。
CREATE INDEX ...
新しい列に必要なインデックス。ロック時間を短縮するには、各ノードでDDLレプリケーションなしで個別に実行しても安全です。
ALTER 必要に応じて、 NOT NULL およびCHECK
コンストレインを追加する列。
BEGIN トランザクション、 DROP 追加したトリガー、 ALTER TABLE
は列に必要なDEFAULT を追加します。
列を削除しているため、テーブルに依存するビュー、プロシージャなどを再作成する必要がある場合があります。列を``CASCADE``ドロップする場合は、それを参照していたものを保証再作成する必要があるので注意してください。
他のタイプの変更¶
ALTER TYPE
ステートメントは複製されますが、影響を受けるテーブルはロックされません。
このDDLを使用する場合、ユーザは新しいタイプを使用する前に、すべてのノードでステートメントが正常に実行されたことを保証必要があります。これは、
bdr.wait_slot_confirm_lsn() ファンクションを使用して実現できます。
例、
ALTER TYPE contact_method ADD VALUE email;
SELECT bdr.wait_slot_confirm_lsn(NULL, NULL);
DMLステートメントで新しい値を使用する前に、 DDLがすべてのノードに書き込まれたことを保証します。
DDLのように動作するBDRFunctions¶
次のBDR管理機能はDDLのように機能します。これは、 DDLレプリケーションがアクティブでDDLフィルター設定で許可されている場合、グローバルロックを取得しようとし、アクションがレプリケートされることを意味します。詳細については、個々の機能の文書を参照してください。
複製セット管理
bdr.create_replication_set
bdr.alter_replication_set
bdr.drop_replication_set
bdr.replication_set_add_table
bdr.replication_set_remove_table
bdr.replication_set_add_ddl_filter
bdr.replication_set_remove_ddl_filter
コンフリクトマネジメント
bdr.alter_table_conflict_detection
bdr.column_timestamps_enable
bdr.column_timestamps_disable
シークエンス管理
bdr.alter_sequence_set_kind
ストリーミングトリガー
bdr.create_conflict_trigger
bdr.create_transform_trigger
bdr.drop_trigger