By default, all data from all published tables will be replicated to the
appropriate subscribers. The replicated data can be reduced by using a
<firstterm>row filter</firstterm>. A user might choose to use row filters
for behavioral, security or performance reasons. If a published table sets a
row filter, a row is replicated only if its data satisfies the row filter
expression. This allows a set of tables to be partially replicated. The row
filter is defined per table. Use a <literal>WHERE</literal> clause after the
table name for each published table that requires data to be filtered out.
The <literal>WHERE</literal> clause must be enclosed by parentheses. See
<xref linkend="sql-createpublication"/> for details.
デフォルトでは、すべてのパブリッシュされたテーブルのすべてのデータが適切なサブスクライバーにレプリケーションされます。
レプリケーションされたデータは、行フィルタを使用して削減できます。
ユーザは、動作、セキュリティまたはパフォーマンス上の理由で行フィルタの使用を選択できます。
パブリッシュされたテーブルに行フィルタが設定されている場合、行はそのデータが行フィルタ式を満たす場合にのみレプリケーションされます。
これにより、一連のテーブルを部分的にレプリケーションできます。
行フィルタはテーブルごとに定義されます。
データのフィルタ処理が必要なパブリッシュされたテーブルごとに、テーブル名の後にWHERE
句を使用します。
WHERE
句はカッコで囲む必要があります。
詳細はCREATE PUBLICATIONを参照してください。
Row filters are applied <emphasis>before</emphasis> publishing the changes.
If the row filter evaluates to <literal>false</literal> or <literal>NULL</literal>
then the row is not replicated. The <literal>WHERE</literal> clause expression
is evaluated with the same role used for the replication connection (i.e.
the role specified in the
<link linkend="sql-createsubscription-params-connection"><literal>CONNECTION</literal></link>
clause of the <xref linkend="sql-createsubscription"/>). Row filters have
no effect for <command>TRUNCATE</command> command.
行フィルタは、変更を発行する前に適用されます。
行フィルタがfalse
またはNULL
と評価される場合、行はレプリケーションされません。
WHERE
句の式は、レプリケーション接続に使用されるロールと同じロール(CREATE SUBSCRIPTIONのCONNECTION
句で指定されたロール)で評価されます。
TRUNCATE
コマンドに対しては、行フィルタは無効です。
The <literal>WHERE</literal> clause allows only simple expressions. It
cannot contain user-defined functions, operators, types, and collations,
system column references or non-immutable built-in functions.
WHERE
句では単純な式のみを使用できます。
ユーザ定義関数、演算子、型、照合、システム列参照、不変でない組み込み関数は使用できません。
If a publication publishes <command>UPDATE</command> or
<command>DELETE</command> operations, the row filter <literal>WHERE</literal>
clause must contain only columns that are covered by the replica identity
(see <xref linkend="sql-altertable-replica-identity"/>). If a publication
publishes only <command>INSERT</command> operations, the row filter
<literal>WHERE</literal> clause can use any column.
パブリケーションがUPDATE
またはDELETE
操作をパブリッシュする場合、行フィルタWHERE
句には、レプリカアイデンティティの対象となる列のみを含める必要があります(REPLICA IDENTITY
を参照)。
パブリケーションがINSERT
操作のみをパブリッシュする場合、行フィルタWHERE
句は任意の列を使用できます。
Whenever an <command>UPDATE</command> is processed, the row filter
expression is evaluated for both the old and new row (i.e. using the data
before and after the update). If both evaluations are <literal>true</literal>,
it replicates the <command>UPDATE</command> change. If both evaluations are
<literal>false</literal>, it doesn't replicate the change. If only one of
the old/new rows matches the row filter expression, the <command>UPDATE</command>
is transformed to <command>INSERT</command> or <command>DELETE</command>, to
avoid any data inconsistency. The row on the subscriber should reflect what
is defined by the row filter expression on the publisher.
UPDATE
が処理されるたびに、行フィルタ式は古い行と新しい行の両方に対して評価されます(つまり、更新前後のデータを使用します)。
両方の評価がtrue
の場合、UPDATE
変更がレプリケーションされます。
両方の評価がfalse
の場合、変更はレプリケーションされません。
古い行と新しい行のいずれか1つのみが行フィルタ式に一致する場合、データの不整合を回避するためにUPDATE
がINSERT
またはDELETE
に変換されます。
サブスクライバーの行は、パブリッシャーの行フィルタ式で定義されている内容を反映する必要があります。
If the old row satisfies the row filter expression (it was sent to the
subscriber) but the new row doesn't, then, from a data consistency
perspective the old row should be removed from the subscriber.
So the <command>UPDATE</command> is transformed into a <command>DELETE</command>.
古い行が行フィルタ式を満たしていて(サブスクライバーに送信された)、新しい行が満たさない場合、データの整合性の観点から、古い行はサブスクライバーから削除される必要があります。
したがって、UPDATE
はDELETE
に変換されます。
If the old row doesn't satisfy the row filter expression (it wasn't sent
to the subscriber) but the new row does, then, from a data consistency
perspective the new row should be added to the subscriber.
So the <command>UPDATE</command> is transformed into an <command>INSERT</command>.
古い行が行フィルタ式を満たさず(サブスクライバーに送信されなかった)、新しい行がそれを満たす場合は、データの整合性の観点から、新しい行をサブスクライバーに追加する必要があります。
したがって、UPDATE
はINSERT
に変換されます。
<xref linkend="logical-replication-row-filter-transformations-summary"/> summarizes the applied transformations. 表 29.1は、適用された変換を要約します。
表29.1 UPDATE
変換要約
古い行 | 新しい行 | 変換 |
---|---|---|
一致せず | 一致せず | レプリケーションしない |
一致せず | 一致 | INSERT |
一致 | 一致せず | DELETE |
一致 | 一致 | UPDATE |
If the publication contains a partitioned table, the publication parameter
<link linkend="sql-createpublication-params-with-publish-via-partition-root"><literal>publish_via_partition_root</literal></link>
determines which row filter is used. If <literal>publish_via_partition_root</literal>
is <literal>true</literal>, the <emphasis>root partitioned table's</emphasis>
row filter is used. Otherwise, if <literal>publish_via_partition_root</literal>
is <literal>false</literal> (default), each <emphasis>partition's</emphasis>
row filter is used.
パブリケーションにパーティション化テーブルが含まれている場合、パブリケーションパラメータpublish_via_partition_root
によって使用される行フィルタが決定されます。
publish_via_partition_root
がtrue
の場合、ルートのパーティション化テーブルの行フィルタが使用されます。
それ以外の場合、publish_via_partition_root
がfalse
(デフォルト)の場合、パーティションの行フィルタがそれぞれ使用されます。
If the subscription requires copying pre-existing table data
and a publication contains <literal>WHERE</literal> clauses, only data that
satisfies the row filter expressions is copied to the subscriber.
サブスクリプションで既存のテーブル・データをコピーする必要があり、パブリケーションにWHERE
句が含まれている場合、行フィルタ式を満たすデータのみがサブスクライバーにコピーされます。
If the subscription has several publications in which a table has been
published with different <literal>WHERE</literal> clauses, rows that satisfy
<emphasis>any</emphasis> of the expressions will be copied. See
<xref linkend="logical-replication-row-filter-combining"/> for details.
サブスクリプションに複数のパブリケーションがあり、テーブルが異なるWHERE
句でパブリッシュされている場合は、式のanyを満たす行がコピーされます。
詳細は29.4.6を参照してください。
Because initial data synchronization does not take into account the
<link linkend="sql-createpublication-params-with-publish"><literal>publish</literal></link>
parameter when copying existing table data, some rows may be copied that
would not be replicated using DML. Refer to
<xref linkend="logical-replication-snapshot"/>, and see
<xref linkend="logical-replication-subscription-examples"/> for examples.
初期データ同期では、既存のテーブルデータをコピーする際にpublish
パラメータが考慮されないため、DMLを使用してレプリケーションされない行がコピーされる場合があります。
29.8.1および29.2.2の例を参照してください。
If the subscriber is in a release prior to 15, copy pre-existing data doesn't use row filters even if they are defined in the publication. This is because old releases can only copy the entire table data. サブスクライバーが15より前のリリースにある場合、既存のデータのコピーでは、パブリケーションで定義されていても行フィルタは使用されません。 これは、古いリリースではテーブルデータ全体しかコピーできないためです。
If the subscription has several publications in which the same table has
been published with different row filters (for the same
<link linkend="sql-createpublication-params-with-publish"><literal>publish</literal></link>
operation), those expressions get ORed together, so that rows satisfying
<emphasis>any</emphasis> of the expressions will be replicated. This means all
the other row filters for the same table become redundant if:
サブスクリプションに複数のパブリケーションがあり、その中で同じテーブルが異なる行フィルタを使用してパブリッシュされている場合(同じパブリッシュ
操作の場合)、これらの式はOR結合され、式のいずれかを満たす行がレプリケーションされます。
これは、次の場合、同じテーブルの他のすべての行フィルタが冗長になることを意味します。
One of the publications has no row filter. パブリケーションの1つに行フィルタがない。
One of the publications was created using
<link linkend="sql-createpublication-params-for-all-tables"><literal>FOR ALL TABLES</literal></link>.
This clause does not allow row filters.
パブリケーションの1つがFOR ALL TABLES
を使用して作成された。
この句では行フィルタを使用できません。
One of the publications was created using
<link linkend="sql-createpublication-params-for-tables-in-schema"><literal>FOR TABLES IN SCHEMA</literal></link>
and the table belongs to the referred schema. This clause does not allow
row filters.
パブリケーションの1つがFOR TABLES IN SCHEMA
を使用して作成され、テーブルは参照されたスキーマに属している。
この句では、行フィルタは使用できません。
Create some tables to be used in the following examples. 次の例で使用するテーブルをいくつか作成します。
test_pub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); CREATE TABLE test_pub=# CREATE TABLE t2(d int, e int, f int, PRIMARY KEY(d)); CREATE TABLE test_pub=# CREATE TABLE t3(g int, h int, i int, PRIMARY KEY(g)); CREATE TABLE
Create some publications. Publication <literal>p1</literal> has one table
(<literal>t1</literal>) and that table has a row filter. Publication
<literal>p2</literal> has two tables. Table <literal>t1</literal> has no row
filter, and table <literal>t2</literal> has a row filter. Publication
<literal>p3</literal> has two tables, and both of them have a row filter.
いくつかのパブリケーションを作成します。
パブリケーションp1
には1つのテーブルt1
があり、そのテーブルには行フィルタがあります。
パブリケーションp2
には2つのテーブルがあります。
テーブルt1
には行フィルタがなく、テーブルt2
には行フィルタがあります。
パブリケーションp3
には2つのテーブルがあり、両方に行フィルタがあります。
test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 WHERE (a > 5 AND c = 'NSW'); CREATE PUBLICATION test_pub=# CREATE PUBLICATION p2 FOR TABLE t1, t2 WHERE (e = 99); CREATE PUBLICATION test_pub=# CREATE PUBLICATION p3 FOR TABLE t2 WHERE (d = 10), t3 WHERE (g = 10); CREATE PUBLICATION
<command>psql</command> can be used to show the row filter expressions (if
defined) for each publication.
psql
を使用して、各パブリケーションの行フィルタ式(定義されている場)を表示することができます。
test_pub=# \dRp+ Publication p1 Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ----------+------------+---------+---------+---------+-----------+---------- postgres | f | t | t | t | t | f Tables: "public.t1" WHERE ((a > 5) AND (c = 'NSW'::text)) Publication p2 Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ----------+------------+---------+---------+---------+-----------+---------- postgres | f | t | t | t | t | f Tables: "public.t1" "public.t2" WHERE (e = 99) Publication p3 Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ----------+------------+---------+---------+---------+-----------+---------- postgres | f | t | t | t | t | f Tables: "public.t2" WHERE (d = 10) "public.t3" WHERE (g = 10)
<command>psql</command> can be used to show the row filter expressions (if
defined) for each table. See that table <literal>t1</literal> is a member
of two publications, but has a row filter only in <literal>p1</literal>.
See that table <literal>t2</literal> is a member of two publications, and
has a different row filter in each of them.
psql
を使用して、各テーブルの行フィルタ式(定義されている場合)を表示できます。
テーブルt1
は2つのパブリケーションのメンバですが、p1
にのみ行フィルタがあります。
テーブルt2
は2つのパブリケーションのメンバですが、それぞれに異なる行フィルタがあります。
test_pub=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- a | integer | | not null | b | integer | | | c | text | | not null | Indexes: "t1_pkey" PRIMARY KEY, btree (a, c) Publications: "p1" WHERE ((a > 5) AND (c = 'NSW'::text)) "p2" test_pub=# \d t2 Table "public.t2" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- d | integer | | not null | e | integer | | | f | integer | | | Indexes: "t2_pkey" PRIMARY KEY, btree (d) Publications: "p2" WHERE (e = 99) "p3" WHERE (d = 10) test_pub=# \d t3 Table "public.t3" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- g | integer | | not null | h | integer | | | i | integer | | | Indexes: "t3_pkey" PRIMARY KEY, btree (g) Publications: "p3" WHERE (g = 10)
On the subscriber node, create a table <literal>t1</literal> with the same
definition as the one on the publisher, and also create the subscription
<literal>s1</literal> that subscribes to the publication <literal>p1</literal>.
サブスクライバーノードで、パブリッシャーと同じ定義のテーブルt1
を作成し、パブリケーションp1
をサブスクライブするサブスクリプションs1
も作成します。
test_sub=# CREATE TABLE t1(a int, b int, c text, PRIMARY KEY(a,c)); CREATE TABLE test_sub=# CREATE SUBSCRIPTION s1 test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1' test_sub-# PUBLICATION p1; CREATE SUBSCRIPTION
Insert some rows. Only the rows satisfying the <literal>t1 WHERE</literal>
clause of publication <literal>p1</literal> are replicated.
いくつかの行を挿入します。
パブリケーションp1
のt1 WHERE
句を満たす行のみがレプリケーションされます。
test_pub=# INSERT INTO t1 VALUES (2, 102, 'NSW'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (3, 103, 'QLD'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (4, 104, 'VIC'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (5, 105, 'ACT'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (6, 106, 'NSW'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (7, 107, 'NT'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (8, 108, 'QLD'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES (9, 109, 'NSW'); INSERT 0 1 test_pub=# SELECT * FROM t1; a | b | c ---+-----+----- 2 | 102 | NSW 3 | 103 | QLD 4 | 104 | VIC 5 | 105 | ACT 6 | 106 | NSW 7 | 107 | NT 8 | 108 | QLD 9 | 109 | NSW (8 rows)
test_sub=# SELECT * FROM t1; a | b | c ---+-----+----- 6 | 106 | NSW 9 | 109 | NSW (2 rows)
Update some data, where the old and new row values both
satisfy the <literal>t1 WHERE</literal> clause of publication
<literal>p1</literal>. The <command>UPDATE</command> replicates
the change as normal.
古い行の値と新しい行の値の両方がパブリケーションp1
のt1 WHERE
句を満たすデータを更新します。
UPDATE
は、通常のように変更をレプリケーションします。
test_pub=# UPDATE t1 SET b = 999 WHERE a = 6; UPDATE 1 test_pub=# SELECT * FROM t1; a | b | c ---+-----+----- 2 | 102 | NSW 3 | 103 | QLD 4 | 104 | VIC 5 | 105 | ACT 7 | 107 | NT 8 | 108 | QLD 9 | 109 | NSW 6 | 999 | NSW (8 rows)
test_sub=# SELECT * FROM t1; a | b | c ---+-----+----- 9 | 109 | NSW 6 | 999 | NSW (2 rows)
Update some data, where the old row values did not satisfy
the <literal>t1 WHERE</literal> clause of publication <literal>p1</literal>,
but the new row values do satisfy it. The <command>UPDATE</command> is
transformed into an <command>INSERT</command> and the change is replicated.
See the new row on the subscriber.
古い行の値はパブリケーションp1
のt1 WHERE
句を満たしていませんが、新しい行の値はこの句を満たしているデータを更新します。
UPDATE
はINSERT
に変換され、変更がレプリケーションされます。
サブスクライバーの新しい行を参照してください。
test_pub=# UPDATE t1 SET a = 555 WHERE a = 2; UPDATE 1 test_pub=# SELECT * FROM t1; a | b | c -----+-----+----- 3 | 103 | QLD 4 | 104 | VIC 5 | 105 | ACT 7 | 107 | NT 8 | 108 | QLD 9 | 109 | NSW 6 | 999 | NSW 555 | 102 | NSW (8 rows)
test_sub=# SELECT * FROM t1; a | b | c -----+-----+----- 9 | 109 | NSW 6 | 999 | NSW 555 | 102 | NSW (3 rows)
Update some data, where the old row values satisfied
the <literal>t1 WHERE</literal> clause of publication <literal>p1</literal>,
but the new row values do not satisfy it. The <command>UPDATE</command> is
transformed into a <command>DELETE</command> and the change is replicated.
See that the row is removed from the subscriber.
古い行の値がパブリケーションp1
のt1 WHERE
句を満たしていますが、新しい行の値がこの句を満たしていないデータを更新します。
UPDATE
はDELETE
に変換され、変更がレプリケーションされます。
行がサブスクライバーから削除されていることを確認します。
test_pub=# UPDATE t1 SET c = 'VIC' WHERE a = 9; UPDATE 1 test_pub=# SELECT * FROM t1; a | b | c -----+-----+----- 3 | 103 | QLD 4 | 104 | VIC 5 | 105 | ACT 7 | 107 | NT 8 | 108 | QLD 6 | 999 | NSW 555 | 102 | NSW 9 | 109 | VIC (8 rows)
test_sub=# SELECT * FROM t1; a | b | c -----+-----+----- 6 | 999 | NSW 555 | 102 | NSW (2 rows)
The following examples show how the publication parameter
<link linkend="sql-createpublication-params-with-publish-via-partition-root"><literal>publish_via_partition_root</literal></link>
determines whether the row filter of the parent or child table will be used
in the case of partitioned tables.
次の例は、パブリケーションパラメータpublish_via_partition_root
によって、親テーブルまたは子テーブルの行フィルタがパーティション化されたテーブルで使用されるかどうかがどのように決定されるかを示しています。
Create a partitioned table on the publisher. パブリッシャーでパーティション化テーブルを作成します。
test_pub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); CREATE TABLE test_pub=# CREATE TABLE child PARTITION OF parent DEFAULT; CREATE TABLE
Create the same tables on the subscriber. サブスクライバー上に同じテーブルを作成します。
test_sub=# CREATE TABLE parent(a int PRIMARY KEY) PARTITION BY RANGE(a); CREATE TABLE test_sub=# CREATE TABLE child PARTITION OF parent DEFAULT; CREATE TABLE
Create a publication <literal>p4</literal>, and then subscribe to it. The
publication parameter <literal>publish_via_partition_root</literal> is set
as true. There are row filters defined on both the partitioned table
(<literal>parent</literal>), and on the partition (<literal>child</literal>).
パブリケーションp4
を作成し、サブスクライブします。
パブリケーションパラメータpublish_via_partition_root
はtrueに設定されています。
行フィルタは、パーティション化テーブル(parent
)とパーティション(child
)の両方に定義されています。
test_pub=# CREATE PUBLICATION p4 FOR TABLE parent WHERE (a < 5), child WHERE (a >= 5) test_pub-# WITH (publish_via_partition_root=true); CREATE PUBLICATION
test_sub=# CREATE SUBSCRIPTION s4 test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s4' test_sub-# PUBLICATION p4; CREATE SUBSCRIPTION
Insert some values directly into the <literal>parent</literal> and
<literal>child</literal> tables. They replicate using the row filter of
<literal>parent</literal> (because <literal>publish_via_partition_root</literal>
is true).
一部の値を親
および子
テーブルに直接挿入します。
これらの値は、親
の行フィルタを使用してレプリケーションされます(publish_via_partition_root
がtrueであるため)。
test_pub=# INSERT INTO parent VALUES (2), (4), (6); INSERT 0 3 test_pub=# INSERT INTO child VALUES (3), (5), (7); INSERT 0 3 test_pub=# SELECT * FROM parent ORDER BY a; a --- 2 3 4 5 6 7 (6 rows)
test_sub=# SELECT * FROM parent ORDER BY a; a --- 2 3 4 (3 rows)
Repeat the same test, but with a different value for <literal>publish_via_partition_root</literal>.
The publication parameter <literal>publish_via_partition_root</literal> is
set as false. A row filter is defined on the partition (<literal>child</literal>).
同じテストを、異なる値publish_via_partition_root
で繰り返します。
パブリケーションパラメータpublish_via_partition_root
は偽に設定されています。
行フィルタがパーティション(child
)に定義されています。
test_pub=# DROP PUBLICATION p4; DROP PUBLICATION test_pub=# CREATE PUBLICATION p4 FOR TABLE parent, child WHERE (a >= 5) test_pub-# WITH (publish_via_partition_root=false); CREATE PUBLICATION
test_sub=# ALTER SUBSCRIPTION s4 REFRESH PUBLICATION; ALTER SUBSCRIPTION
Do the inserts on the publisher same as before. They replicate using the
row filter of <literal>child</literal> (because
<literal>publish_via_partition_root</literal> is false).
パブリッシャーで挿入を前と同じように実行します。
これらはchild
の行フィルタを使用してレプリケーションされます(publish_via_partition_root
がfalseであるため)。
test_pub=# TRUNCATE parent; TRUNCATE TABLE test_pub=# INSERT INTO parent VALUES (2), (4), (6); INSERT 0 3 test_pub=# INSERT INTO child VALUES (3), (5), (7); INSERT 0 3 test_pub=# SELECT * FROM parent ORDER BY a; a --- 2 3 4 5 6 7 (6 rows)
test_sub=# SELECT * FROM child ORDER BY a; a --- 5 6 7 (3 rows)