当需要升级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. MessagePack Java Jackson Dataformat - 安装

    中文标题[MessagePack 的 Jackson 数据格式] 本页面中的所有示例程序,请到代码库 https://github.com/cwiki-us-demo/serialize-deseri ...

  2. CodeForces 1197 D Yet Another Subarray Problem

    题面 不得不说CF还是很擅长出这种让人第一眼看摸不着头脑然后再想想就发现是个SB题的题的hhh(请自行断句). 设sum[]为前缀和数组,那么区间 [l,r]的价值为 sum[r] - sum[l-1 ...

  3. flask框架(七): flask模板

    1.模板的使用 Flask使用的是Jinja2模板,所以其语法和Django无差别 2.自定义模板方法 Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render ...

  4. CUDA-F-2-0-CUDA编程模型概述1

    Abstract: 本文介绍CUDA编程模型的简要结构,包括写一个简单的可执行的CUDA程序,一个正确的CUDA核函数,以及相应的调整设置内存,线程来正确的运行程序. Keywords: CUDA编程 ...

  5. SpringMVC——返回值类型

    1.void作为返回值类型 如果你的方法写成了Void就跟原来Servlet含义是差不多的 @RequestMapping("/index*") public void first ...

  6. Taro 遇到的坑

    1.createSelectorQuery无法获取节点宽高 业务场景: 列表需要在最后一页底部显示 ‘我是有底线的~’ 提示,但是如果数据只有一页且不占满屏幕的话,就不显示.需要判断 ‘我是有底线的~ ...

  7. 微信小程序_(校园视)开发视频的展示页_上

    微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...

  8. Centos-Redhat下远程桌面的方法 & Redhat改Centos源

    折腾了好几天才搞定,Redhat下远程桌面的方法,首先保证本身已经装了桌面,并且可以ssh访问 由于系统中自带python2环境,装了anaconda以及它带的python3环境,这个必须存在(前提) ...

  9. 阿里云服务器yum源更新问题

    阿里云官网也给出了yum卸载重装以及修改源为阿里云内网的文档.步骤这里就不说了,可点击下面的链接进行参考 https://help.aliyun.com/knowledge_detail/670864 ...

  10. Java——重写hashCode()和euqals()方法

    1.顺序表的问题 查找和去重效率较低 对于这样的顺序表来说,如果需要查找元素,就需要从第一个元素逐个检查,进行查找.对于需要去重的存储来说,每次存入一个元素之前,就得将列表中的每个元素都比对一遍,效率 ...