CREATE SUBSCRIPTION — 新しいサブスクリプションを定義する
CREATE SUBSCRIPTIONsubscription_nameCONNECTION 'conninfo' PUBLICATIONpublication_name[, ...] [ WITH (subscription_parameter[=value] [, ... ] ) ]
CREATE SUBSCRIPTIONは新しい論理レプリケーションのサブスクリプションを追加します。
サブスクリプションを作成するユーザは、サブスクリプションの所有者になります。
サブスクリプションの名前は現在のデータベースに存在するどのサブスクリプションの名前とも異なるものでなければなりません。
サブスクリプションはパブリッシャーへのレプリケーション接続を表します。 そのため、このコマンドはローカルのカタログに定義を追加するだけでなく、通常はパブリッシャーのレプリケーションスロットも作成します。
サブスクリプションが最初に無効にされていない限り、このコマンドが実行されるトランザクションがコミットされた時点で、新しいサブスクリプションに対してデータを複製する論理レプリケーションワーカーが開始されます。
サブスクリプションを作成するには、現在のデータベースに対するCREATE権限に加えて、pg_create_subscriptionロールの権限が必要です。
subscription_name #新しいサブスクリプションの名前です。
CONNECTION 'conninfo' #パブリッシャーデータベースへの接続を定義するlibpq接続文字列です。 詳細は34.1.1を参照してください。
PUBLICATION publication_name [, ...] #パブリッシャー上のパブリケーションで、サブスクリプションの対象となるものの名前です。
WITH ( subscription_parameter [= value] [, ... ] ) #この句は、サブスクリプションのオプションのパラメータを指定します。
以下のパラメータは、サブスクリプションの作成時に何が行われるかを制御します。
connect (boolean) #
CREATE SUBSCRIPTIONコマンドがパブリッシャーに接続する必要があるかどうかを指定します。
デフォルトはtrueです。
これをfalseに設定すると、create_slot、enabled、およびcopy_dataの値が、falseに強制的に設定されます。
(connectをfalseに設定することは、create_slot、enabled、またはcopy_dataをtrueに設定することと組み合わせることはできません。)
このオプションがfalseに設定されると接続が行われないため、テーブルはサブスクライブされません。
レプリケーションを開始するには、レプリケーションスロットを手動で作成し、サブスクリプションを有効にして、サブスクリプションをリフレッシュする必要があります。
例については31.2.3を参照してください。
create_slot (boolean) #
このコマンドがパブリッシャー上にレプリケーションスロットを作るかどうかを指定します。
デフォルトはtrueです。
falseに設定した場合、パブリッシャーのスロットを何か他の方法で作成するのは利用者の責任です。
例については31.2.3を参照してください。
enabled (boolean) #
サブスクリプションが複製の動作をすぐに行うか、あるいは単に設定をするだけでまだ開始しないかを指定します。
デフォルトはtrueです。
slot_name (string) #使用するパブリッシャーのレプリケーションスロットの名前です。 デフォルトでは、サブスクリプションの名前をスロット名として使用します。
slot_nameをNONEに設定すると、サブスクリプションに紐付けられたレプリケーションスロットがなくなります。
そのようなサブスクリプションは、enabledとcreate_slotの両方をfalseに設定しなければなりません。
これはレプリケーションスロットを後で手作業で作成する場合に使用してください。
例については31.2.3を参照してください。
以下のパラメータは、作成された後のサブスクリプションのレプリケーション動作を制御します。
binary (boolean) #
(テキストではなく)バイナリ形式でデータを送信するようにサブスクリプションがパブリッシャーに要求するかどうかを指定します。
デフォルトはfalseです。
最初のテーブル同期コピー(copy_data参照)も同じ形式を使います。
バイナリ形式はテキスト形式よりも高速かもしれませんが、マシンアーキテクチャやPostgreSQLのバージョンをまたがる移植性が落ちます。
バイナリ形式はデータ型に非常に依存します。
例えば、テキスト形式では問題なく動作するにも関わらず、smallintの列からintegerの列へのコピーを認めません。
このオプションが有効になっている場合でも、バイナリ送受信関数を持つデータ型のみがバイナリ形式で転送されます。
最初の同期ではデータ型すべてがバイナリ送受信関数を持つことが必要なことに注意してください。さもないと同期は失敗します(送受信関数についてはCREATE TYPEを参照してください)。
バージョンをまたいでレプリケーションをしている場合は、パブリッシャーはあるデータ型に対してバイナリ送信関数を持っているものの、サブスクライバーはその型に対してバイナリ受信関数を持っていないという場合があり得ます。
その場合、データ転送は失敗し、binaryオプションは使えません。
パブリッシャーのバージョンがPostgreSQL 16より前の場合、最初のテーブル同期では、binary = trueであってもテキストフォーマットが使用されます。
copy_data (boolean) #
サブスクリプションの対象となるパブリケーションの既存データが、レプリケーションの開始時にコピーされるかどうかを指定します。
デフォルトはtrueです。
パブリケーションにWHERE句が含まれている場合、コピーされるデータに影響します。
詳細は注釈を参照してください。
copy_data = trueがoriginパラメータとどのように相互作用するかの詳細については、注釈を参照してください。
streaming (enum) #
進行中のトランザクションのストリーミングをこのサブスクリプションで有効にするかどうかを指定します。
デフォルト値はoffで、すべてのトランザクションはパブリッシャーで完全にデコードされ、その後でのみ全体としてサブスクライバーに送られることを意味します。
onに設定すると、受信した変更は一時ファイルに書き込まれ、トランザクションがパブリッシャーでコミットされ、サブスクライバーで受信された後にのみ適用されます。
parallelに設定すると、受信した変更は、可能であれば、パラレル適用ワーカーの1つを介して直接適用されます。
ストリーミングトランザクションを扱えるパラレル適用ワーカーがない場合、変更は一時ファイルに書き込まれ、トランザクションがコミットされた後に適用されます。
パラレル適用ワーカーでエラーが発生した場合、リモートトランザクションの終了LSNがサーバーログで報告されない場合があることに注意してください。
synchronous_commit (enum) #
このパラメータの値は、このサブスクリプションの適用されるワーカープロセスのsynchronous_commitの設定をオーバーライドします。
デフォルト値はoffです。
論理レプリケーションではoffを使用するのが安全です。
そうすることで、同期の失敗によりサブスクライバーがトランザクションを失った場合でも、パブリッシャーからデータが再送されます。
同期論理レプリケーションを行う場合は別の設定が適切かもしれません。
論理レプリケーションのワーカーは書き込みおよび吐き出しの位置をパブリッシャーに報告しますが、同期レプリケーションを行っているときは、パブリッシャーは実際に吐き出しがされるのを待ちます。
これはつまり、サブスクリプションが同期レプリケーションで使われている時に、サブスクライバーのsynchronous_commitをoffに設定すると、パブリッシャーでのCOMMITの遅延が増大するかもしれない、ということを意味します。
この場合、synchronous_commitをlocalまたはそれ以上に設定することが有利になりえます。
two_phase (boolean) #
このサブスクリプションに対して2相コミットを有効にするかどうかを指定します。
デフォルトはfalseです。
2相コミットが使用可能な場合、プリペアドトランザクションはPREPARE TRANSACTION時にサブスクライバーに送信され、サブスクライバー上でも2相トランザクションとして処理されます。
それ以外の場合、プリペアドトランザクションはコミット時にのみサブスクライバーに送信され、サブスクライバーによってただちに処理されます。
2相コミットの実装では、レプリケーションが最初のテーブル同期フェーズを正常に完了している必要があります。
そのため、two_phaseがサブスクリプションに対して有効になっている場合でも、内部の2相状態は初期化フェーズが完了するまで一時的に「pending(保留)」のままです。
実際の2相状態を知るには、pg_subscriptionのsubtwophasestate列を参照してください。
disable_on_error (boolean) #
パブリッシャーからのデータレプリケーション中にサブスクリプションワーカーによってエラーが検出された場合に、サブスクリプションを自動的に無効にするかどうかを指定します。
デフォルトはfalseです。
password_required (boolean) #
trueに設定すると、このサブスクリプションの結果として行われるパブリッシャーへの接続はパスワード認証を使用しなければならず、パスワードは接続文字列の一部として指定されなければなりません。
サブスクリプションがスーパーユーザによって所有されている場合、この設定は無視されます。
デフォルトはtrueです。
スーパーユーザのみがこの値をfalseに設定できます。
run_as_owner (boolean) #
trueの場合、レプリケーションのアクションはすべてサブスクリプション所有者として行われます。
falseの場合、レプリケーションワーカーは各テーブルでそのテーブルの所有者としてアクションを行います。
後者の設定が一般的にはよりセキュアです。詳細は31.9を参照してください。
デフォルトはfalseです。
origin (string) #
サブスクリプションがパブリッシャーに、オリジンのない変更のみを送信するよう要求するか、オリジンに関係なく変更を送信するよう要求するかを指定します。
originをnoneに設定すると、サブスクリプションはパブリッシャーにオリジンのない変更のみを送信するよう要求します。
originをanyに設定すると、パブリッシャーはオリジンに関係なく変更を送信します。
デフォルトはanyです。
copy_data = trueがoriginパラメータとどのように相互作用するかの詳細については、注釈を参照してください。
boolean型のパラメータを指定する場合、= valueの部分を省略できます。これはTRUEを指定するのと同じです。
サブスクリプションとパブリケーションのインスタンスの間のアクセス制御をどのように設定するかの詳細については、31.9を参照してください。
レプリケーションスロットを作成する(デフォルトの動作です)場合、CREATE SUBSCRIPTIONをトランザクションブロックの内側で実行することはできません。
同じデータベースクラスタに接続するサブスクリプション(例えば、同一のクラスタ内のデータベース間で複製を行う、あるいは同一のデータベース内で複製を行う)の作成は、同じコマンド内でレプリケーションスロットが作成されない場合にのみ成功します。
そうでない場合、CREATE SUBSCRIPTIONの呼び出しはハングアップします。
これを動作させるには、(関数pg_create_logical_replication_slotをプラグイン名pgoutputで使って)レプリケーションスロットを別に作り、パラメータcreate_slot = falseを使ってサブスクリプションを作成してください。
例については31.2.3を参照してください。
これは実装上の制限で、将来のリリースでは解決されるかもしれません。
パブリケーション内のテーブルにWHERE句がある場合、expressionが偽またはNULLと評価される行はパブリッシュされません。
サブスクリプションに、同じテーブルが異なるWHERE句でパブリッシュされた複数のパブリケーションがある場合、(パブリッシュ操作を参照する)式のいずれかが満たされると行がパブリッシュされます。
WHERE句が異なる場合、パブリケーションのいずれかにWHERE句がないか(パブリッシュ操作を参照する)パブリケーションがFOR ALL TABLESまたはFOR TABLES IN SCHEMAとして宣言されている場合、行は他の式の定義に関係なく常にパブリッシュされます。
サブスクライバーのバージョンがPostgreSQL 15より前の場合、最初のデータ同期フェーズでは行のフィルタリングは無視されます。
この場合、後続のフィルタリングと互換性のない最初にコピーされたデータの削除を検討したくなるでしょう。
最初のデータ同期では、既存のテーブルデータをコピーする際にパブリケーションpublishパラメータが考慮されないため、DMLを使用してレプリケートされない行がコピーされる場合があります。
例については31.2.2を参照してください。
同じテーブルが異なる列リストでパブリッシュされた複数のパブリケーションを持つサブスクリプションはサポートされません。
後で追加できるように、存在しないパブリケーションを指定できます。
これはpg_subscriptionが存在しないパブリケーションを持つことができることを意味します。
サブスクリプションパラメータのcopy_data = trueとorigin = NONEの組合せを使用する場合、初期同期テーブルデータはパブリッシャーから直接コピーされます。これは、そのデータの真のオリジンを認識できないことを意味します。
そのパブリッシャーにもサブスクリプションがある場合、コピーされたテーブルデータはさらに上流から発生した可能性があります。
このシナリオは検出され、警告がユーザに向けて記録されますが、警告は潜在的な問題を示しているだけです。
コピーされたデータの発生元が本当に望んだものであること、またはそうでないことを保証する必要なチェックを行うのは、ユーザの責任です。
どのテーブルが(そのパブリッシャーで作成された他のサブスクリプションのために)ローカルでないオリジンを含む可能性があるのかを知るためには、次のSQL問い合わせを試してください。
# substitute <pub-names> below with your publication name(s) to be queried
# 以下の<pub-names>を問い合わせるパブリケーションの名前で置き換えてください
SELECT DISTINCT PT.schemaname, PT.tablename
FROM pg_publication_tables PT,
pg_subscription_rel PS
JOIN pg_class C ON (C.oid = PS.srrelid)
JOIN pg_namespace N ON (N.oid = C.relnamespace)
WHERE N.nspname = PT.schemaname AND
C.relname = PT.tablename AND
PT.pubname IN (<pub-names>);
パブリケーションmypublicationおよびinsert_onlyのテーブルを複製する、リモートサーバへのサブスクリプションを作成し、コミット後、すぐにレプリケーションを開始します。
CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
PUBLICATION mypublication, insert_only;
パブリケーションinsert_onlyのテーブルを複製するリモートサーバへのサブスクリプションを作成しますが、後に有効化するまではレプリケーションを開始しません。
CREATE SUBSCRIPTION mysub
CONNECTION 'host=192.168.1.50 port=5432 user=foo dbname=foodb'
PUBLICATION insert_only
WITH (enabled = false);
CREATE SUBSCRIPTIONはPostgreSQLの拡張です。