postgresql从库搭建--逻辑复制

1 物理复制及逻辑复制对比

前文做了PostgreSQL物理复制的部署,其有如下主要优点

  • 物理层面完全一致,是主要的复制方式,其类似于Oracle的DG
  • 延迟低,事务执行过程中产生REDO record,实时的在备库apply,事务结束时,备库立马能见到数据
  • 物理复制的一致性、可靠性高,不必担心数据逻辑层面不一致

但是其又在实际使用的场景中存在一些无法满足的需求,例如:

  • 无法满足指定库或部分表的复制需求
  • 将多个数据库实例的数据汇聚到同一个目标库或将一个库的数据分发到多个不同的库
  • 不同的版本之间的复制
  • 不同库名之间的表同步

对于以上场景,物理复制时无法满足的,因此逻辑复制应运而生了。

逻辑复制的复制架构图如下:

图片来源于《PostgreSQL实战》

逻辑复制是基于逻辑解析,其核心原理是逻辑主库将Publication中表的WAL日志解析成一定格式并发送给逻辑备库,逻辑备库Subscription接收到解析后的WAL日志后进行重做,从而实现表数据同步。

2. 逻辑复制的部署

PS: 以下的逻辑从库可以在新的机器上部署,如在原先的从库上修改,需停止原实例,并将recovery.conf文件删除或重命名(如修改为recovery.conf.done)

2.1 修改主库的postgresql.conf

可以基于原先的物理复制的配置文件进行修改,配置逻辑复制主要需调整如下参数

wal_level = logical
max_wal_senders = 10
max_replication_slots = 8

参数简要说明如下

  • wal_level:设置成logical才支持逻辑复制
  • max_wal_senders:由于每个订阅节点和流复制备库在主库上都会占用主库上一个WAL发送进程,因此此参数设置值需大于max_replication_slots参数值加上物理备库数量
  • max_replication_slots:设置值需大于订阅节点的数量

2.2 修改逻辑从库的postgresql.conf

逻辑从库的postgresql.conf也可以在物理复制的基础上修改,与主库不同的是主要修改如下参数

wal_level = logical
max_replication_slots = 8
max_logical_replication_workers = 8

参数简要说明

  • wal_level:设置成logical才支持逻辑复制,逻辑从库可以视情况设置
  • max_replication_slots:设置数据库复制槽数量,应大于订阅节点的数量
  • max_logical_replication_workers:设置逻辑复制进程数,应大于订阅节点的数量,并且给表同步预留一些进程数量,此参数默认值为4

2.3 创建逻辑复制账号

postgres=# CREATE USER logical_repl REPLICATION LOGIN CONNECTION LIMIT 8 ENCRYPTED PASSWORD ‘logical_repl‘; 

CREATE ROLE

逻辑复制用户需要REPLICATION权限即可,可以不需要SUPERUSER权限,之后需要在发布节点上将需要同步的表赋权给logical_repl用户,使logical_repl账号具有对这些表的读权限。

2.4 在逻辑主库上创建库及表

/** 创建用于逻辑复制的主库 */ [[email protected] data]$ createdb sourcedb [[email protected] data]$ psql -d sourcedb psql (11.4) Type "help" for help. sourcedb=# create table logical_tb1(id int primary key,name varchar(20));

2.5 逻辑从库上创建库及表

/** 在逻辑从库上创建不同的库 */[[email protected] data]$ createdb desdb [[email protected] data]$ psql -d desdb psql (11.4) Type "help" for help. desdb=# create table logical_tb1(id int primary key,name varchar(20)); CREATE TABLE desdb=# 

注:逻辑复制的表结构需要手动在从库创建

2.6 在逻辑主库上创建发布

/** 在发布主库上创建发布pub1,注意实在sourcedb库下执行 */
 sourcedb=# CREATE PUBLICATION pub1 FOR TABLE logical_tb1; CREATE PUBLICATION

如果需发布多张表 则表名间用逗号(,)分割,如果需发布所有库,则将FOR TABLE 调整为FOR ALL TABLES。

此时可以查看到如下信息

sourcedb=# SELECT * FROM pg_publication;
 pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate
---------+----------+--------------+-----------+-----------+-----------+-------------
 pub1    |       10 | f            | t         | t         | t         | t
(1 row)

字段说明如下:

  • pubname: 指发布的名称
  • pubowner: 指发布的属主,可以和pg_user视图的usesysid字段关联查询得到属主具体信息
  • puballtables:是否发布数据库中的所有表,t表示发布数据库中所有已存在的表和以后新建的表
  • pubinsert: t表示仅发布表上的INSERT操作
  • pubupdate: t表示仅发布表上的UPDATE操作
  • pubdelete: t表示仅发布表上的DELETE操作

2.7 在逻辑从库上创建订阅

desdb=# CREATE SUBSCRIPTION sub1 CONNECTION ‘host=192.168.56.32 port=5432 user=logical_repl dbname=sourcedb password=logical_repl‘ PUBLICATION pub1;
NOTICE:  created replication slot "sub1" on publisher
CREATE SUBSCRIPTION

创建成功后,可以在逻辑主库上查询到如下信息:

sourcedb=# SELECT slot_name,plugin,slot_type,database,active,restart_lsn    FROM pg_replication_slots where slot_name=‘sub1‘;
 slot_name |  plugin  | slot_type | database | active | restart_lsn
-----------+----------+-----------+----------+--------+-------------
 sub1      | pgoutput | logical   | sourcedb | t      | 0/6022D30
(1 row)

在逻辑从库上可以查询到如下信息:

desdb=# SELECT * FROM pg_subscription;
 subdbid | subname | subowner | subenabled |                                      subconninfo                                      | subslotname | subsynccommit | subpublications
---------+---------+----------+------------+---------------------------------------------------------------------------------------+-------------+---------------+-----------------
   24995 | sub1    |       10 | t          | host=192.168.56.32 port=5432 user=logical_repl dbname=sourcedb password=logical_repl | sub1        | off           | {pub1}
(1 row)

2.8 给复制账号授权

因为步骤2.3中只创建了复制账号并未对需要复制的表进行授权,因此,此时逻辑从库的日志中有如下错误

2019-10-10 15:57:21.847 CST [27443] ERROR: could not start initial contents copy for table "public.logical_tb1": ERROR: permission denied for table logical_tb1
2019-10-10 15:57:21.848 CST [24722] LOG: background worker "logical replication worker" (PID 27443) exited with exit code 1

因此 ,现在需要对复制用户授权。

sourcedb=# GRANT USAGE ON SCHEMA public TO logical_repl;
GRANT
sourcedb=# GRANT SELECT ON logical_tb1 TO logical_repl;
GRANT

授权后,显示正常

    2019-10-10 16:00:25.959 CST [28204] LOG: logical replication table synchronization worker for subscription "sub1", table "logical_tb1" has started
    2019-10-10 16:00:25.967 CST [28204] LOG: logical replication table synchronization worker for subscription "sub1", table "logical_tb1" has finished

2.9 测试数据同步

在逻辑主库插入数据

/** 在主库插入数据 */
sourcedb=# insert into logical_tb1(id,name) values(1,‘a‘),(2,‘bca‘);
INSERT 0 2

在逻辑从库查看结果

/** 查看数据是否同步完成 */
desdb=# select * from logical_tb1;
 id | name
----+------
  1 | a
  2 | bca
(2 rows)

由此可见数据已同步完成。

2.10 添加复制所需的表

在逻辑主库和逻辑从库均添加一张新表,并添加到发布列表中

/** 主库上创建表结构 */
sourcedb=# create table logical_tb2(id int primary key ,addr varchar(100)); CREATE TABLE
sourcedb=#
/** 从库上创建表结构 */
desdb=# create table logical_tb2(id int primary key ,addr varchar(100)); CREATE TABLE
/** 在主库上给逻辑复制账号授权 */
sourcedb=# GRANT SELECT ON logical_tb2 TO logical_repl;
GRANT
/** 添加新表至发布列表 */
sourcedb=# ALTER PUBLICATION pub1 ADD TABLE logical_tb2;
ALTER PUBLICATION
/** 在主库查看发布列表中的表名 */
sourcedb=# SELECT * FROM pg_publication_tables;
 pubname | schemaname |  tablename
---------+------------+-------------
 pub1    | public     | logical_tb1
 pub1    | public     | logical_tb2
(2 rows)

此时已加入一张表进入发布列表中。

此时在主库写入数据,查看从库情况如下:

/** 主库插入一条记录 */
sourcedb=# insert into logical_tb2(id,addr) values(1,‘beijing‘);
INSERT 0 1
/** 此时在逻辑从库查看,结果却没有数据 */
desdb=# select  * from logical_tb2;
 id | addr
----+------
(0 rows)

因为还需要在从库刷新一下订阅

/** 此时在从库刷新订阅 */
desdb=# ALTER SUBSCRIPTION sub1 REFRESH PUBLICATION;
/** 刷新完成后再查数据已经有数据了 */
ALTER SUBSCRIPTION
desdb=# select  * from logical_tb2;
 id |  addr
----+---------
  1 | beijing
(1 row)

至此,PostgreSQL的逻辑复制也部署完毕。

3. 物理复制与逻辑复制特点和应用场景

PostgreSQL的逻辑复制与物理复制的差异比较突出,在使用中可以根据其特点选择使用哪种复制方式。

  • 逻辑订阅,适合于发布端与订阅端都有读写的情况。
  • 逻辑订阅,更适合于小事务,或者低密度写(轻度写)的同步。如果有大事务、高密度写,逻辑订阅的延迟相比物理复制更高。
  • 逻辑订阅,适合于双向,多向同步。
  • 物理复制,适合于单向同步。
  • 物理复制,适合于任意事务,任意密度写(重度写)的同步。
  • 物理复制,适合于HA、容灾、读写分离。
  • 物理复制,适合于备库没有写,只有读的场景。

想进一步沟通或想了解其他文章的同学可以关注我的微信公众号进行交流

原文地址:https://www.cnblogs.com/gjc592/p/11649315.html

时间: 2024-10-29 18:18:29

postgresql从库搭建--逻辑复制的相关文章

PostgreSQL逻辑复制之pglogical篇

PostgreSQL逻辑复制之slony篇 一.pglogical介绍 pglogical 是 PostgreSQL 的拓展模块, 为 PostgreSQL 数据库提供了逻辑流复制发布和订阅的功能. pglogical 重用了 BDR 项目中的一部分相关技术.pglogical 是一个完全作为PostgreSQL 扩展实现的逻辑复制系统.完全集成,它不需要触发器或外部程序.这种物理复制的替代方法是使用发布/订阅模型复制数据以进行选择性复制的一种高效方法.支持 PG10.9.6.9.5.9.4 ,

DG搭建逻辑备库

逻辑备库是在物理备库的基础上搭建的,所以需要先搭建好物理备库. 备库执行如下操作: [[email protected] ~]$ sqlplus / as sysdba SQL*Plus: Release 11.2.0.3.0 Production onFri Nov 7 15:03:30 2014 Copyright (c) 1982, 2011, Oracle.  All rights reserved. Connected to: Oracle Database 11g Enterpris

搭建逻辑备库

1. 搭建物理备库 2. 在物理备库上停止重做应用,如果备库是RAC,则必须停止所有执行以下语句以外的实例 SQL> alter database recover managed standby database cancel; Database altered. 3. 为角色转换准备主库 这一步仅在执行切换时有用 修改初始化参数: alter system set LOG_ARCHIVE_DEST_1='LOCATION=/oradata/arch/ VALID_FOR=(ONLINE_LOG

oracle11g dataguard物理备库搭建

Dataguard 环境: 操作系统:Redhat6.4 Primary数据库: IP 地址:192.168.1.122 数据库SID:ora11g DB_UNIQUE_NAME:ora11g_primary Standby数据库: IP 地址:192.168.1.123 数据库SID:ora11g DB_UNIQUE_NAME:ora11g_standby (注:oracle数据库版本是11.2.0.1.0) 1.Primary端的配置 (1).检查数据库是否支持 Data Guard(企业版

ORACLE 11G 之DATAGUARD搭建逻辑standby

Oracle Data Guard逻辑备库是利用主库的一个备份首先建立一个物理备库,然后再将其转换为逻辑备库.这之后主库将日志传递到备库,备库利用logminer从主库的日志中解析出主库所执行过的SQL,在备库上重新执行一遍,从而保证与主库的数据在逻辑上保持一致.与物理备库相对应的是,物理备库使用的是redo apply,逻辑备库使用的是sql apply.因此逻辑备库仅仅保证数据与主库是在逻辑上是一致的,从而逻辑备库可以处于open状态下并进行相应的DML操作. 在转换physical备库到l

[zz]阿里云计算:CentOS+nginx+Django+Postgresql web环境搭建

原文链接: http://www.cnblogs.com/AllStarGIS/p/3788518.html 参考链接: 1. http://www.cnblogs.com/zhouej/archive/2012/03/25/2379646.html 2. http://ec58.com/archives/2836 最近在在万网和阿里云上分别购买了一个域名和一台云服务器,打算用来做点什么.昨天吃完晚饭稍作休息开始对这个新奇的玩意作了些了解并着手配置其运行环境,今早凌晨4点多才弄得7788,为此也

verilog逻辑复制

本文转自:http://www.cnblogs.com/linjie-swust/archive/2012/03/27/FPGA_verilog.html 在FPGA设计中经常使用到逻辑复制,逻辑复制也用在很多场合. 1.    信号驱动级数非常大,扇出很大,需要增加驱动力 逻辑复制最常使用的场合时调整信号的扇出.如果某个信号需要驱动后级很多单元,此时该信号的扇出非常大,那么为了增加这个信号的驱动能力,一种办法就是插入多级Buffer,但是这样虽然能增加驱动能力,但是也增加了这个信号的路径延时.

linux下oracle11G DG搭建(三):围绕备库搭建操作

环境 名称 主库 备库 主机名 bjsrv shsrv 软件版本 RedHat Enterprise5.5.Oracle 11g 11.2.0.1 RedHat Enterprise5.5.Oracle 11g 11.2.0.1 三.围绕备库操作: 1.备库-修改初始化参数文件 $cd$ORACLE_HOME/dbs $df -h $vi initshdb.ora 修改简要说明: *.audit_file_dest='/u01/app/oracle/admin/sh/adump' //审计文件存

mysql复制原理/基于库的多线程复制原理/基于BLGC的多线程复制原理

单线程主从复制: 从库向主库请求binlog,并将binlog转存到自己的relaylog中,从库重做binlog里面的sql, 主要由以下三个线程完成. dump thread: 在主库上,发送binlog io thread: 在slave上,接收,转存,请求binlog sql thread :在slave 上,重做binlog 基于库的多线程复制原理: 从库向主库请求binlog,并将binlog转存到自己的relaylog中,从库重做binlog里面的sql, 主要由以下三个线程完成.