通常、サブスクライバーのテーブルはパブリッシャーのテーブルと同じように定義されます。そのため、パブリッシャーテーブルにGENERATED(生成)列が存在する場合、サブスクライバーテーブルにも対応する生成列が存在します。
この場合、常にサブスクライバーテーブルの生成列の値が使用されます。
例えば以下の場合、サブスクライバーテーブルの生成列の値は、サブスクライバー列の計算から取得されることに注意してください。
/* pub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED); /* pub # */ INSERT INTO tab_gen_to_gen VALUES (1),(2),(3); /* pub # */ CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen; /* pub # */ SELECT * FROM tab_gen_to_gen; a | b ---+--- 1 | 2 2 | 3 3 | 4 (3 rows) /* sub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED); /* sub # */ CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1; /* sub # */ SELECT * from tab_gen_to_gen; a | b ---+---- 1 | 100 2 | 200 3 | 300 (3 rows)
実際、バージョン18.0より前では、論理レプリケーションは生成列を全くパブリッシュしません。
しかし、生成列の値を通常の列に複製することが望ましい場合もあります。
この機能は、出力プラグインを介してPostgreSQL以外のデータベースにデータを複製する場合、特に対象データベースが生成列をサポートしていない場合に有用です。
生成列はデフォルトではパブリッシュされませんが、ユーザは格納生成列を通常の列と同様にパブリッシュすることを選択できます。
これには2つの方法があります。
PUBLICATIONパラメータのpublish_generated_columnsをstoredに設定します。
これは、PostgreSQL論理レプリケーションに、パブリケーションのテーブルが持つ現在または将来の格納生成列をパブリッシュするように指示します。
どの格納生成列がパブリッシュされるかを明示的に指定する、テーブルの列リストを設定します。
どのテーブル列をパブリッシュするかを決定する際には、列リストが優先され、publish_generated_columnsパラメータの効果を上書きします。
以下の表は、論理レプリケーションに生成列が含まれる場合の動作をまとめたものです。 生成列のパブリッシュが有効になっていない場合と、有効になっている場合の結果を示しています。
表29.2 レプリケーション結果の概要
| 生成列をパブリッシュするか否か? | パブリッシャーテーブルの列 | サブスクライバーテーブルの列 | 結果 |
|---|---|---|---|
| いいえ | 生成列 | 生成列 | パブリッシャーテーブルの列はレプリケーションされません。サブスクライバーテーブルの生成列の値を使用します。 |
| いいえ | 生成列 | 通常の列 | パブリッシャーテーブルの列はレプリケーションされません。サブスクライバーテーブルの通常の列の値を使用します。 |
| いいえ | 生成列 | --存在しない-- | パブリッシャーテーブルの列はレプリケーションされません。何も起こりません。 |
| はい | 生成列 | 生成列 | エラー。サポートされていません。 |
| はい | 生成列 | 通常の列 | パブリッシャーテーブルの列がサブスクライバーテーブルの列にレプリケーションされます。 |
| はい | 生成列 | --存在しない-- | エラー。サブスクライバーテーブルに列が存在しないことが報告されます。 |
現在のところ、同じテーブルが異なる列リストでパブリッシュされている複数のパブリケーションで構成されるサブスクリプションはサポートされていません。 29.5を参照してください。
同様の状況は、あるパブリケーションが生成列をパブリッシュしている一方で、同じサブスクリプション内の別のパブリケーションが同じテーブルに対して生成列をパブリッシュしていない場合にも発生します。
サブスクライバーが18より前のリリースの場合、生成列のパブリッシュがパブリッシャーで規定されている場合でも、初期テーブル同期ではそれらの列はコピーされません。