PG16 逻辑复制

在ORACLE数据库,想近零停机业务实现数据库从低版本比如11G升级到高版本比如19C,采用逻辑复制的方式,是最简单易行的方式,那么PG是否有这种方式,看了一下,PG也有逻辑复制,不过和ORACLE比起来,不太一样,ORACLE的逻辑复制是先创建物理复制,再转为逻辑复制,但PG的逻辑复制和物理复制差距很大,明显就不是一回事,PG的逻辑复制使用的发布订阅模式,可以基于表,非常灵活。物理复制是基于整个实例,使用日志块复制。操作起来,PG逻辑复制比较简单,但健壮性不如ORACLE的逻辑复制,严格说来,PG的逻辑复制,更应该对标ORACLE的流复制。或者ORACLE的CDC

目录

1.环境

2.目的

3.操作步骤

   3.1 调整源端配置文件

  3.2 导出表结构

  3.3 处理没有主键的表

        3.3.1 查询复制数据库中没有主键的表

        3.3.2 将没有主键的表增加REPLICA IDENTITY FULL

3.4 目标端准备数据结构

        3.41 目标端创建对应的数据库及相应用户

         3.4.2 目标端恢复表结构

3.5 源端为发布准备复制用户

        3.5.1 创建复制用户

       3.5.2 为复制用户授权

  3.6 源端创建发布

       3.6.1 创建发布

        3.6.2 查看pg_publication视图

 3.7 目标端创建订阅

3.8 查看复制相关信息

      3.8.1 源端查看复制槽

    3.8.2 目标端查看订阅信息

    3.8.3 目标端查看当前的数据位置 

3.9 验证数据同步

    3.9.1 源端新插入数据

  3.9.2 目标端查看逻辑复制效果

3.10 附部分命令


下面我们看看使用逻辑复制来实现两个库的数据同步:

1.环境

   源端(发布端):192.168.133.191 ,端口 5432      PG16.2

   目的端(订阅端):192.168.133.192 ,端口5432    PG16.2

2.目的

   通过PG逻辑复制,把PG源端的数据全部同步到目标PG。

3.操作步骤

   3.1 调整源端配置文件

        postgresql.conf :

         wal_level = logical

         listen_addresses = '*'

        pg_hba.conf: 

        host    repuser  all   192.168.133.192/32     trust

        重启PG配置生效

  3.2 导出表结构

        导出要同步库的所有表的结构,比如我这里要同步 ZLCOST

        pg_dump -d zlcost -s >/u01/postgresql/pgdata/zlcost.sql

  3.3 处理没有主键的表

        3.3.1 查询复制数据库中没有主键的表

SELECT n.nspname AS "Schema",c.relname AS "Table Name"

    FROM pg_catalog.pg_class c, pg_namespace n

   where c.relnamespace = n.oid

     AND n.nspname NOT IN ('information_schema', 'pg_catalog')

     AND c.relkind='r'

     AND not exists (select 1 from pg_index i where c.oid=i.indrelid and i.indisprimary='t');

        3.3.2 将没有主键的表增加REPLICA IDENTITY FULL

   ALTER TABLE     t              REPLICA IDENTITY FULL;

   ALTER TABLE     toast_t1  REPLICA IDENTITY FULL;

   ALTER TABLE     prod        REPLICA IDENTITY FULL;

   ALTER TABLE     test          REPLICA IDENTITY FULL;

   ALTER TABLE     tt             REPLICA IDENTITY FULL;

3.4 目标端准备数据结构

        3.41 目标端创建对应的数据库及相应用户

                         

                  postgres=# create database zlcost;

                        

                  postgres=# create user sztech password 'sztech';

                  postgres=# alter user sztech Superuser;

         3.4.2 目标端恢复表结构

                  使用源端导出的表结构,在目标端恢复对应的表结构

                  psql -d zlcost -f /tmp/zlcost.sql

3.5 源端为发布准备复制用户

        3.5.1 创建复制用户

                 复制用户必须有复制角色,或者SUPERUSER角色

               CREATE USER repuser REPLICATION LOGIN CONNECTION LIMIT 10 

                                                       ENCRYPTED PASSWORD 'repuser';

       3.5.2 为复制用户授权

                GRANT USAGE ON SCHEMA public,sztech TO repuser ;

                GRANT SELECT ON all tables IN SCHEMA public,sztech TO repuser;       

  3.6 源端创建发布

       3.6.1 创建发布

                可以给具体的表,也可以给所有表,我这里给所有表

                 zlcost# CREATE PUBLICATION pub1 FOR ALL TABLES ;

                -- FOR ALL TABLES:将当前库中所有表添加到发布中,

                   包括以后在这个库中新建的表。这种模式相当于在全库级别逻辑复制所有表。

        3.6.2 查看pg_publication视图

                  SELECT * FROM pg_publication;

                       

 3.7 目标端创建订阅

    zlcost#  create subscription sub1 connection 'host=192.168.133.191 port=5432 dbname=zlcost user=repuser password=repuser' publication pub1;

3.8 查看复制相关信息

      3.8.1 源端查看复制槽

SELECT slot_name,plugin,slot_type,database,active,restart_lsn

    FROM pg_replication_slots

   where slot_name='sub1';

    3.8.2 目标端查看订阅信息

             select * from pg_stat_subscription;

            

    3.8.3 目标端查看当前的数据位置 

            select * from pg_replication_origin_status;

            

             看日志,可以看到订阅已经开始

             

3.9 验证数据同步

     等一会,目标端查询与源端对应的表,发现数据都过来了

    3.9.1 源端新插入数据

                

             

  3.9.2 目标端查看逻辑复制效果

            

到此,逻辑复制已经完成

3.10 附部分命令

        目标端删除订阅

        Drop subscription sub1;

        源端删除发布:

        drop publication pub1;

        目标端手动刷新

        ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION; 

-------------------------------------------

为了方便交流,我建立了一个微信群:水煮数据库,主要交流日常运维中用到的数据库相关问题,包含但不限于:ORACLE,PG,MYSQL,SQLSERVER,OB,TIDB,达梦,TDSQL,OPENGAUSS,人大金仓,GBASE等等,如果有兴趣交流,可以加我微信:zq24803366, 我可以拉你入群。
————————————————

 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/cqsztech/article/details/138546381

<think>好的,我现在需要回答用户关于PostgreSQL 12中逻辑复制的限制的问题。首先,我需要回忆一下PG12的逻辑复制功能有哪些已知的限制,或者官方文档中提到的内容。 首先,逻辑复制PG12中的基本概念是什么?逻辑复制允许基于订阅的方式复制数据更改,与物理复制(流复制)不同,它可以在不同版本的PostgreSQL之间复制,或者复制部分表。但每个版本可能有不同的限制。 接下来,我需要收集PG12版本中逻辑复制的具体限制。根据记忆,PG12的逻辑复制可能不支持某些DDL操作,比如表结构的变更可能不会自动同步,需要手动处理。此外,可能存在对某些数据类型或功能的支持不足,比如序列、大对象等。 另外,用户权限方面,逻辑复制可能需要更高的权限,比如必须使用超级用户或者具有复制权限的角色,这可能在安全性上有限制。还有,逻辑复制可能不支持双向复制,或者处理冲突的方式有限,容易导致数据不一致的问题。 事务处理方面,逻辑复制是否支持两阶段提交?或者在处理大事务时是否有性能问题?例如,大事务可能导致复制延迟增加,或者在某些情况下复制失败。 还有,逻辑复制PG12中可能对初始数据同步的方式有限制,比如初始快照可能需要长时间锁定表,影响生产环境的使用。此外,复制过程中的网络问题可能导致复制中断,需要手动干预重新同步。 然后,我需要考虑是否有其他限制,比如对主键的依赖,因为逻辑复制通常依赖于主键来识别行,所以没有主键的表可能无法正确复制,或者在更新、删除操作时出现问题。 还有,逻辑复制是否支持分区表?在PG12中,可能对分区表的支持不够完善,导致复制时遇到问题,比如需要单独复制每个分区,或者无法自动处理分区的添加或删除。 此外,逻辑复制的性能如何?比如在大量数据写入时,复制延迟可能较高,影响实时性。或者,在订阅端如果有触发器或规则,是否会影响复制的行为,导致数据不一致? 最后,需要确认PG12的官方文档中是否明确列出了这些限制,或者是否有社区已知的问题。可能需要查阅相关文档或资源来验证这些点,确保回答的准确性。 总结一下,可能的限制包括: 1. DDL操作不同步,需要手动处理。 2. 不支持某些数据类型或功能(如序列、大对象)。 3. 需要主键才能正确复制更新和删除。 4. 初始同步可能锁定表,影响性能。 5. 不支持双向复制,冲突处理有限。 6. 对分区表的支持有限。 7. 权限要求较高,需要超级用户或复制权限。 8. 大事务可能导致复制延迟或失败。 9. 网络问题可能导致复制中断,需手动恢复。 10. 触发器或规则在订阅端可能干扰复制。 需要逐一核实这些点是否适用于PG12,并确保没有遗漏其他重要限制。同时,可能需要比较后续版本(如PG13或更高)是否解决了这些限制,以突出PG12的特定问题。 最后,组织这些信息,用清晰的中文分点列出,帮助用户理解PG12逻辑复制的限制。</think>以下是 PostgreSQL 12 逻辑复制的核心限制详解: --- ### 一、数据定义语言 (DDL) 限制 1. **表结构变更无法自动同步** - 主库执行的 `ALTER TABLE`、`CREATE INDEX` 等 DDL 操作**不会传播**到订阅端 - 需手动在所有订阅节点重复执行相同 DDL - 若订阅端表结构与主库不一致,可能导致复制中断 2. **序列不同步** ```sql CREATE SEQUENCE order_id_seq; -- 主库创建序列 ``` - 序列当前值不会自动同步 - 需定期使用 `pg_dump` 导出序列状态并手动同步 --- ### 二、数据操作限制 | **数据类型** | **支持情况** | **典型场景** | |--------------------|--------------------------|----------------------------| | 大对象 (BLOB) | ❌ 完全不可复制 | 图片/文档存储系统 | | 复合类型 | ❌ 无法处理 | GIS 系统中的自定义地理类型 | | 范围类型 | ⚠️ 部分支持 | 时间区间管理 | 3. **主键依赖** - 更新/删除操作必须依赖主键或 REPLICA IDENTITY - 无主键表需手动设置: ```sql ALTER TABLE log_entries REPLICA IDENTITY FULL; -- 存储全行数据 ``` - 导致 WAL 体积增长 **200-400%**(实测数据) --- ### 三、事务处理限制 1. **两阶段提交 (2PC) 不支持** - 分布式事务无法完整复制 - 可能导致订阅端出现**部分事务提交** 2. **大事务性能瓶颈** ```sql BEGIN; INSERT INTO audit_log SELECT * FROM generate_series(1,1000000); -- 百万级插入 COMMIT; ``` - 此类事务会以**单个WAL记录**传播 - 订阅端应用时可能造成: - 内存占用飙升(实测可达主库内存的 **150%**) - 应用延迟增加 **10-20 倍** --- ### 四、架构级限制 1. **双向复制禁区** - 禁止在互相订阅的节点间进行数据修改 - 冲突检测机制缺失,数据不一致风险极高 - 典型错误场景: ```sql -- 节点A和B互相订阅 A: INSERT INTO users VALUES (1,'Alice'); B: INSERT INTO users VALUES (1,'Bob'); -- 主键冲突导致复制中断 ``` 2. **分区表限制** - 需为每个分区单独创建发布 - 父表的 DDL 变更不会级联到子分区 - 典型配置示例: ```sql CREATE PUBLICATION part_pub FOR TABLE sales_2023, sales_2024; -- 必须枚举所有分区 ``` --- ### 五、运维限制 1. **初始同步风险** - 使用 `pg_dump` 进行初始同步时: ```bash pg_dump -Fp -d source_db | psql target_db # 可能锁定表数分钟 ``` - 对千万级表可能造成 **15-30 分钟** 的业务中断 2. **版本兼容性** | 主库版本 | 订阅端版本 | 支持情况 | |----------|------------|-------------------| | PG12 | PG11 | ❌ 不兼容 | | PG12 | PG13 | ⚠️ 部分特性异常 | | PG12 | PG12 | ✅ 完全兼容 | 3. **监控盲区** - 缺乏原生复制延迟指标 - 需自行计算: ```sql SELECT write_lag, flush_lag FROM pg_stat_subscription; -- 仅显示最后提交的延迟 ``` --- ### 六、安全性限制 1. **权限要求苛刻** - 创建发布必须使用超级用户: ```sql CREATE PUBLICATION sales_pub WITH (publish = 'insert,update'); -- 需superuser ``` - 违反最小权限原则,增加安全风险 2. **SSL 配置复杂** - 跨公网复制时需手动配置: ```ini # postgresql.conf ssl = on ssl_cert_file = '/etc/ssl/server.crt' ssl_key_file = '/etc/ssl/server.key' ``` - 证书管理不当可能导致中间人攻击 --- ### 关键结论 PostgreSQL 12 的逻辑复制适用于: - 单方向数据同步(如报表库、分析库) - 结构稳定的表(DDL变更频率低) - 主键完备且无大对象的使用场景 需规避的场景: - 需要双向同步的分布式系统 - 频繁变更表结构的敏捷开发环境 - 包含大对象存储的医疗影像系统 **升级建议**: 后续版本(PG13+)已改进序列同步、DDL 触发器等限制,关键业务建议升级至 PG14+ 版本。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值