On Sun, 4 Jul 2021 at 15:53, Avi Weinberg <a...@gilat.com> wrote: > I'm using logical replication to copy data from multiple tables to a > single destination table. At times the structure of the source table needs > to change. However, not all source table will have their structure updated > at the same time. Let's assume, for example, a column type needs to be > changed (but solution needs to work for column addition, deletion, rename > etc.). What is the preferable approach: > > > > 1. To add another column to the destination table where its type will > be the new type. Source tables, that have the new column type, will write > to the new column. While source tables with old column type will write to > the old column. A view will do the proper casting and will show a single > column to user. > 2. Add a new table (versioned: table_name_v2) where source tables that > have a new structure will write to the new destination table, while old > source tables will write to the old destination table. A view with UNION > and casting will combine all tables. > 3. A better way? > > Does the below not work for all alter table changes on publisher. I have been testing on a demo setup pg14beta, and subscribers are able to catch up fine.
on publisher (port 5001) postgres=# alter table t alter COLUMN name type bigint using name::bigint; on subscriber (port 5002) postgres=# alter table t alter COLUMN name type bigint using name::bigint; ALTER TABLE postgres=# alter subscription mysub refresh publication; this should work for all the cases for ddl changes right. -- demo -- create table on pub and sub postgres@db:~/playground/logical_replication$ psql -p 5001 psql (14beta1) Type "help" for help. postgres=# create table t(id int primary key, name text); CREATE TABLE postgres=# \q postgres@db:~/playground/logical_replication$ psql -p 5002 psql (14beta1) Type "help" for help. postgres=# create table t(id int primary key, name text); CREATE TABLE postgres=# \q -- insert dummy data to check sub rx changes postgres@db:~/playground/logical_replication$ psql -p 5001 psql (14beta1) Type "help" for help. postgres=# insert into t values (1, 1::text); INSERT 0 1 postgres=# \q postgres@db:~/playground/logical_replication$ psql -p 5002 psql (14beta1) Type "help" for help. postgres=# table t; id | name ----+------ (0 rows) postgres=# alter subscription mysub refresh publication; -- this is because i dropped table with publication enabled ALTER SUBSCRIPTION postgres=# table t; id | name ----+------ 1 | 1 (1 row) postgres=# \q -- alter table alter column change type on pub postgres@db:~/playground/logical_replication$ psql -p 5001 psql (14beta1) Type "help" for help. postgres=# alter table t alter COLUMN name type bigint using name::bigint; ALTER TABLE postgres=# \q -- alter table alter column change type on sub postgres@db:~/playground/logical_replication$ psql -p 5002 psql (14beta1) Type "help" for help. postgres=# alter table t alter COLUMN name type bigint using name::bigint; ALTER TABLE postgres=# \q -- insert new data based on new column type postgres@db:~/playground/logical_replication$ psql -p 5001 psql (14beta1) Type "help" for help. postgres=# insert into t values (2, 100000000000000); INSERT 0 1 postgres=# \q -- check new data on sub postgres@db:~/playground/logical_replication$ psql -p 5002 psql (14beta1) Type "help" for help. postgres=# table t; id | name ----+----------------- 1 | 1 2 | 100000000000000 (2 rows) postgres=# \q --alter table alter col type on pub and insert data postgres@db:~/playground/logical_replication$ psql -p 5001 psql (14beta1) Type "help" for help. postgres=# alter table t alter COLUMN name type text using name::text; ALTER TABLE postgres=# insert into t values (3, 'three'); INSERT 0 1 postgres=# \q --alter table alter col type on sub, changes will not come till refresh pub postgres@db:~/playground/logical_replication$ psql -p 5002 psql (14beta1) Type "help" for help. postgres=# table t; id | name ----+----------------- 1 | 1 2 | 100000000000000 (2 rows) postgres=# alter table t alter COLUMN name type text using name::text; ALTER TABLE postgres=# table t; id | name ----+----------------- 1 | 1 2 | 100000000000000 (2 rows) postgres=# alter subscription mysub refresh publication; -- refresh would get back changes ALTER SUBSCRIPTION postgres=# table t; id | name ----+----------------- 1 | 1 2 | 100000000000000 3 | three (3 rows) or have I misunderstood the question? -- Thanks, Vijay Mumbai, India