当需要升级PostgreSQL时,可以使用多种方法。为了避免应用程序停机,不是所有升级postgres的方法都适合,如果避免停机是必须的,那么可以考虑使用复制作为升级方法,并且根据方案,可以选择使用逻辑复制或物理(流)复制来处理此任务。我们来看看PostgreSQL中逻辑和物理复制之间的区别。然后,我们将更详细地探讨如何使用逻辑复制完成升级,并通过这样做,避免应用程序停机。在后面的文章中,我们将研究物理复制。我们已经在之前的系列文章中讨论了几种可用于升级或迁移旧版PostgreSQL到新版PostgreSQL版本的方法,使用pg_dumpall进行PostgreSQL升级和使用pg_dump/pg_restore进行PostgreSQL升级。但是,这两种方法都涉及到应用程序的停机时间。

1      逻辑复制的类型

这里我们介绍两种您可以实现的复制类型:

1.使用内置逻辑复制在PostgreSQL 10和11版本之间进行复制。

2.使用pglogical的扩展在PostgreSQL 11和PostgreSQL 9.4或低于PostgreSQL11版本之间进行复制。

我们可能会选择通过复制作为升级方法,以最大限度地减少应用程序的停机时间。一旦所有数据都被复制到最新版本的另一个PostgreSQL服务器上,您只需将应用程序切换到新服务器,停机时间最短,但这当然取决于应用程序的复杂性。

PostgreSQL中的逻辑复制允许用户执行表级别的复制,并允许备库可以写入。而PostgreSQL中的物理复制是块级复制。在这种情况下,主服务器中的每个数据库都将复制到备用数据库,并且备库以只读方式打开并不可以写入,我们将物理复制称为流复制。

通过逻辑复制,备用数据库可以从多个主服务器启用复制。在需要将数据从多个PostgreSQL数据库(OLTP)复制到单个PostgreSQL服务器以进行报表和数据仓库业务的情况下,这么做会对业务有所帮助。

逻辑复制的最大优势之一是逻辑复制允许我们将旧版本的PostgreSQL的DML复制到更高版本。物理流复制只有在主数据库版本和备用数据库版本都是相同的时才有效。最佳的实施方案,是主库和备库使用相同的版本。

2      PostgreSQL 10和11版本之间的复制

从PostgreSQL 10开始,默认情况下PostgreSQL支持逻辑复制。因此,您可以轻松地将PostgreSQL 10数据库复制到PostgreSQL 11.逻辑复制使用发布和订阅模式。发送更改的节点称为发布者。订阅这些更改的节点称为订阅者。可以有一个或多个订阅者。

2.1      发布者

发布者是从一组表生成的一组更改。它被称为更改集或复制集。发布者只能包含表,不能包含任何其他对象。只支持复制这些表上的DML操作变更,但不能复制DDL操作变更。

在发布者中,可以选择要复制的DML类型:INSERT或DELETE或UPDATE或ALL。默认情况下复制全部。您必须在要发布的表上设置标识,以将UPDATES和DELETES复制到订阅者。标识有助于识别要更新或删除的行。

表的主键是其默认标识。还可以使用NO NULL值创建唯一索引作为标识。如果没有主键或具有NO NULL的唯一索引,则可以将replica_identity设置为FULL。当标识设置为FULL时,postgres将整行用作键。当然,这可能使复制效率下降。

如果在UPDATE或DELETE操作之后将没有主键和非默认标识的表添加到发布中,则可能会发生错误。

2.2      订阅者

订阅者可以订阅一个或多个发布者。在添加订阅之前,必须确保已在订阅节点中创建了要复制的表,当然你可以通过在发布节点转储模式元数据到订阅节点实现。

2.3      逻辑复制的一个示例

以下示例步骤仅适用于PostgreSQL 10和11版本之间的逻辑复制。在发布节点上,创建发布。您可以添加所有表,也可以选择将选定的表添加到发布中。

-- For adding ALL Tables in Database

CREATE PUBLICATION percpub FOR ALL TABLES;

-- For adding Selected Tables in Database

CREATE PUBLICATION percpub FOR TABLE scott.employee scott.departments;

在订阅者节点上,创建引用发布者节点上的发布的订阅。如上所述,在创建订阅之前,将表的DDL转储执行到订阅者节点,

$ pg_dump -h publisher_server_ip -p 5432 -d percona -Fc -s -U postgres | pg_restore -d percona -h subscriber_node_ip -p 5432 -U postgres

CREATE SUBSCRIPTION percsub CONNECTION 'host=publisher_server_ip dbname=percona user=postgres password=secret port=5432' PUBLICATION percpub;

上述命令还会复制表中预先存在的数据。如果要禁用预先存在的数据的副本,可以使用以下语法。然后,它将在您运行此命令后才开始将更改复制到发布者。

CREATE SUBSCRIPTION percsub CONNECTION 'host=publisher_server_ip dbname=percona user=postgres password=oracle port=5432' PUBLICATION percpub WITH (copy_data = false);

在发布节点上使用以下命令监视复制。

$ psql

\x

select * from pg_stat_replication;

3       PostgreSQL 9.4和PostgreSQL 11之间的复制

现在,那些比PostgreSQL 10更旧的版本呢?为此,有一个名为pglogical的扩展 ,适用于从9.4到11的版本。使用pglogical,您可以轻松地将PostgreSQL 9.4复制到PostgreSQL 11。

以下步骤演示了使用pglogical扩展在PG 9.4和PG 11之间设置复制的过程。

步骤1将 pgserver_94视为具有数据库的源服务器:在PostgreSQL 9.4上运行的percona_94。创建以下扩展名。

[pgserver_94:] $psql -d percona_94 -c "CREATE EXTENSION pglogical_origin"

CREATE EXTENSION

[pgserver_94:] $psql -d percona_94 -c "CREATE EXTENSION pglogical"

CREATE EXTENSION

步骤2现在,您可以继续添加选定的表或模式中的所有表或多个模式以进行复制。在以下示例中,当其中一个表上没有主键时,可以看到错误。

[pgserver_94:] $psql -d percona_94

psql (9.4.21)

Type "help" for help.

percona_94=# SELECT pglogical.create_node(node_name := 'provider1',dsn := 'host=192.168.0.24 port=5432 dbname=percona_94');

create_node

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

2976894835

(1 row)

percona_94=# SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);

ERROR: table pgbench_history cannot be added to replication set default

DETAIL: table does not have PRIMARY KEY and given replication set is configured to replicate UPDATEs and/or DELETEs

HINT: Add a PRIMARY KEY to the table

percona_94=# ALTER TABLE pgbench_history ADD PRIMARY KEY (tid,aid,delta);

ALTER TABLE

percona_94=# SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);

replication_set_add_all_tables

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

t

(1 row)

步骤3在订阅者节点(即PostgreSQL 11数据库)上,您可以运行类似的命令,如下所示。

创建

pgserver_11,创建以下扩展名。

[pgserver_11:] $psql -d percona_94 -c "CREATE EXTENSION pglogical_origin"

CREATE EXTENSION

[pgserver_11:] $psql -d percona_94 -c "CREATE EXTENSION pglogical"

CREATE EXTENSION

[pgserver_11:] $psql -d percona_11

psql (11.2)

Type "help" for help.

percona_11=# SELECT pglogical.create_node(node_name := 'subscriber1',dsn := 'host=127.0.0.1 port=5432 dbname=percona_11 password=secret');

create_node

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

330520249

(1 row)

percona_11=# SELECT pglogical.create_subscription(subscription_name := 'subscription1',provider_dsn := 'host=192.168.0.24 port=5432 dbname=percona_94 password=secret');

create_subscription

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

1763399739

(1 row)

步骤4然后,您可以通过查询pglogical始终更新的几个表来验证复制状态:

percona_11=# select * from pglogical.local_sync_status;

sync_kind | sync_subid | sync_nspname |   sync_relname   | sync_status | sync_statuslsn

-----------+------------+--------------+------------------+-------------+----------------

f         | 1763399739 | public       | pgbench_accounts | r           | 0/2EB7D48

f         | 1763399739 | public       | pgbench_history  | r           | 0/2EB7D48

f         | 1763399739 | public       | pgbench_tellers  | r           | 0/2EB7D48

f         | 1763399739 | public       | pgbench_branches | r           | 0/2EB7D48

d         | 1763399739 |              |                  | r           | 0/0

(5 rows)

percona_11=# select * from pglogical.subscription;

sub_id   |   sub_name    | sub_origin | sub_target | sub_origin_if | sub_target_if | sub_enabled |             sub_slot_name              |         sub_rep

lication_sets          | sub_forward_origins | sub_apply_delay

------------+---------------+------------+------------+---------------+---------------+-------------+----------------------------------------+----------------

-----------------------+---------------------+-----------------

1763399739 | subscription1 | 2976894835 |  330520249 |    2402836775 |    2049915666 | t           | pgl_percona_11_provider1_subscription1 | {default,defaul

t_insert_only,ddl_sql} | {all}               | 00:00:00

(1 row)

3.1      主键选择

在第2步中,您了解了模式的所有表:public没有主键的表通过创建主键,从而添加到复制集。我选择的主键可能不符合业务逻辑,因为它仅用于演示。但是,当您选择主键时,请确保选择符合程序逻辑的键。它必须始终是唯一的,并使用通常不包含NULL的列。如果不彻底研究主键选择,可能会导致应用程序停机。以下是您可能遇到的示例错误:

[pgserver_94:] $pgbench -c 10 -T 300 -n percona_94

Client 7 aborted in state 12: ERROR: duplicate key value violates unique constraint "pgbench_history_pkey"

DETAIL: Key (tid, aid, delta)=(7, 63268, 2491) already exists.

到目前为止,我们已经看到了如何使用pglogical在较旧版本和较新版本PostgreSQL之间创建复制。设置复制后,您可以轻松地将应用程序切换到最新版本,同时降低停机时间。

跨 PostgreSQL 大版本复制怎么做?| 逻辑复制的更多相关文章

  1. PostgreSQL逻辑复制使用记录

    之前逻辑复制刚刚出来的时候就使用过,但是没有进行整理,这次一个项目需要逻辑复制的自动迁移,再次拾起逻辑复制. 在此之前有两个疑问: 1)同一个表,既有流复制,又有逻辑复制,这样数据会有两份吗? --不 ...

  2. PostgreSQL逻辑复制解密

    在数字化时代的今天,我们都认同数据会创造价值.为了最大化数据的价值,我们不停的建立着数据迁移的管道,从同构到异构,从关系型到非关系型,从云下到云上,从数仓到数据湖,试图在各种场景挖掘数据的价值.而在这 ...

  3. PostgreSQL逻辑复制之pglogical篇

    PostgreSQL逻辑复制之slony篇 一.pglogical介绍 pglogical 是 PostgreSQL 的拓展模块, 为 PostgreSQL 数据库提供了逻辑流复制发布和订阅的功能. ...

  4. 【RMAN】RMAN跨版本恢复(下)--大版本异机恢复

    [RMAN]RMAN跨版本恢复(下)--大版本异机恢复 BLOG文档结构图 ORACLE_SID=ORA1024G 关于10g的跨小版本恢复参考:http://blog.chinaunix.net/u ...

  5. postgresql从库搭建--逻辑复制

    1 物理复制及逻辑复制对比 前文做了PostgreSQL物理复制的部署,其有如下主要优点 物理层面完全一致,是主要的复制方式,其类似于Oracle的DG 延迟低,事务执行过程中产生REDO recor ...

  6. Windows 环境搭建 PostgreSQL 逻辑复制高可用架构数据库服务

    本文主要介绍 Windows 环境下搭建 PostgreSQL 的主从逻辑复制,关于 PostgreSQl 的相关运维文章,网络上大多都是 Linux 环境下的操作,鲜有在 Windows 环境下配置 ...

  7. PostgreSQL逻辑复制之slony篇

    Slony是PostgreSQL领域中最广泛的复制解决方案之一.它不仅是最古老的复制实现之一,它也是一个拥有最广泛的外部工具支持的工具,比如pgAdmin3.多年来,Slony是在PostgreSQL ...

  8. PostgreSQL逻辑复制槽

    Schema | Name | Result data type | Argument data types | Type ------------+------------------------- ...

  9. 第29章 跨战区大PK

    29.1 策略模式 VS 桥梁模式 29.1.1 策略模式 [编程实验]用策略模式实现邮件发送 (1)有文本和超文本两种格式的邮件,将这两种格式封装成两种不同的发送策略. (2)文本邮件和超文本邮件分 ...

随机推荐

  1. HYSBZ - 3813 奇数国 欧拉函数+树状数组(线段树)

    HYSBZ - 3813奇数国 中文题,巨苟题,巨无敌苟!!首先是关于不相冲数,也就是互质数的处理,欧拉函数是可以求出互质数,但是这里的product非常大,最小都2100000,这是不可能实现的.所 ...

  2. hadoop yarn日志分离

    根据hdfs的auditlog以及fsimage分析,yarn的日志文件占用了10%-20%的rpc请求以及文件量,这对namenode的性能有比较大的影响,特别是当集群规模越来越大,会影响生产业务. ...

  3. Vue双向绑定的实现原理系列(一):Object.defineproperty

    了解Object.defineProperty() github源码 Object.defineProperty()方法直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象. ...

  4. mongo数据库的使用

    mongodb 是一个非关系型数据库,跟每一个数据库都没有关系,(mysql 是一个关系型数据库)他以集合(collections)问单位,他长得和 json 一样 mongo 数据库的下载,安装 自 ...

  5. [eclipse]如何修改Eclipse编辑器的字体

    步骤如下, 菜单->"Window"->“Preference”->“General”->“Appearance”->“Colors & Fo ...

  6. Linux 命令速记本

    # 比较1.txt和2.txt的差异 comm [---] .txt .txt # 求1.txt和2.txt的MD5用于区分两个文件是否相同 md5sum .txt .txt #tr 用于转换或删除文 ...

  7. GitHub:IBM

    ylbtech-GitHub:IBM 1.返回顶部   2.返回顶部   3.返回顶部   4.返回顶部   5.返回顶部 1. https://github.com/ibm 2.   6.返回顶部 ...

  8. 2017年内容营销如何提高ROI转化率

    根据2017 CMI报告显示,有近41%的营销人员今年会实施一系列内容营销战略.作为与用户间长期关系的桥梁, 从品牌化输出到信任感的培育,内容营销的影响力迅猛发展. 本次Focussend从互动集成内 ...

  9. 自定义有焦点的TextView实现广告信息左右一直滚动的跑马灯效果

    import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; imp ...

  10. numpy之填充为nan的数据为该列平均值

    # coding=utf-8 import numpy as np ''' 填充nan的数据,为该列的平均值 ''' def fill_ndarray(t1): for i in range(t1.s ...