暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

EPAS 16 备用服务器设置逻辑复制

新智锦绣 2025-03-28
107

点击蓝字关注我们


本文介绍 EPAS 16 中的新增加功能“允许从备用服务器进行逻辑复制”。

此功能使用户能够将数据流式传输到其他PostgreSQL 实例,为开发人员提供了新的工作负载分布选项。此外,它还使备用服务器能够将逻辑更改发布到其他服务器。我们可以在备用服务器上设置逻辑复制,这在 16 以下的版本中是无法实现的。这是 PostgreSQL 16 中最有用的功能之一,它增加了从物理复制备用服务器执行逻辑复制的能力。


一、备用服务器设置逻辑复制的示例


在这个示例中,为了简单起见,我们在同一台服务器上运行 3 个 EPAS 实例,分别使用三个不同的端口。也可以使用三台不同的服务器来实现。

  • 主服务器监听端口 5444,数据目录为 data;

  • 备用服务器监听端口 5445,数据目录为 standby_data1,用于流复制;

  • 订阅服务器监听端口 5446,数据目录为 logical_data,用于逻辑复制。


1.1 在主服务器上


在 postgresql.conf 文件中,需要启用以下参数:

    $ vim var/lib/edb/as16/data/postgresql.conf 
    wal_level = logical
    hot_standby = on
    max_wal_senders = 10  
    max_replication_slots = 10
    hot_standby_feedback = on

    添加 HBA 规则以允许连接,通过编辑文件 var/lib/edb/as16/data/pg_hba.conf。

    重启 Postgres:

      $ usr/edb/as16/bin/pg_ctl -D var/lib/edb/as16/data restart
      waiting for server to shut down.... done
      server stopped
      waiting for server to start....2024-06-10 00:58:29 PDT LOG:  redirecting log output to logging collector process
      2024-06-10 00:58:29 PDT HINT:  Future log output will appear in directory "log".
       done
      server started

      创建两个具有复制权限的用户。一个用于流式传输更改到备用服务器,另一个用于将更改发布到订阅者:

        /usr/edb/as16/bin/psql -d edb
        psql (16.3.0)
        Type "help" for help.
        edb=
        edb=create user repuser with replication password 'edb';
        CREATE ROLE
        edb=create user pubuser with replication password 'edb';
        CREATE ROLE
        edb=
        edb=# \du
                                           List of roles
               Role name       |                         Attributes                         
        -----------------------+--------------------------------------------------
         aq_administrator_role | No inheritance, Cannot login                              +
                               | Profile default
         capture_admin         | No inheritance, Cannot login                              +
                               | Profile default
         enterprisedb          | Superuser, Create role, Create DB, Replication, Bypass RLS+
                               | Profile default
         pubuser               | Replication                                               +
                               | Profile default
         repuser               | Replication                                               +
                               | Profile default

        创建复制槽:

          edb=select pg_create_physical_replication_slot('primary');
           pg_create_physical_replication_slot 
          -------------------------------------
           (primary,)
          (1 row)

          创建示例表以发布:

            edb=create table t1(id int);
            CREATE TABLE
            edb=drop table t1 ;
            DROP TABLE
            edb=create table t1(id int primary key, name char(20));
            CREATE TABLE
            edb=create table t2(id int primary key, name char(20));
            CREATE TABLE
            edb=insert into t1 values (1'supriya');
            INSERT 0 1
            edb=insert into t2 values (1'payal');
            INSERT 0 1
            edb=table t1;
             id |         name         
            ----+----------------------
              1 | supriya             
            (1 row)


            edb=table t2;
             id |         name         
            ----+----------------------
              1 | payal               
            (1 row)

            授予 pubuser 选择表的权限:

              printf("hello world!");

              创建发布:

                edb=# create publication testpub for all tables;
                CREATE PUBLICATION

                检查复制槽和其他详细信息:

                  edb=# select * from pg_publication;
                    oid  | pubname | pubowner | puballtables | pubinsert | pubupdate | pubdelete | pubtruncate | pubviaroot 
                  -------+---------+----------+--------------+-----------+-----------+-----------+-------------+------------
                   16399 | testpub |       10 | t            | t         | t         | t         | t           | f
                  (1 row)


                  edb=# select * from pg_publication
                  pg_publication            pg_publication_namespace  pg_publication_rel        pg_publication_tables     
                  edb=# select * from pg_publication_tables ;
                   pubname | schemaname | tablename | attnames  | rowfilter 
                  ---------+------------+-----------+-----------+-----------
                   testpub | public     | t1        | {id,name} | 
                   testpub | public     | t2        | {id,name} | 
                  (2 rows)


                  edb=# \dt
                            List of relations
                   Schema | Name | Type  |    Owner     
                  --------+------+-------+--------------
                   public | t1   | table | enterprisedb
                   public | t2   | table | enterprisedb
                  (2 rows)


                  edb=#  


                  edb=# select * from pg_replication_slots ;
                   slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase 
                  | conflicting 
                  -----------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+-----------
                  +-------------
                   primary   |        | physical  |        |          | f         | f      |            |      |              |             |                     |            |               | f         

                  (1 row)


                  edb=# \q


                  1.2 在备用服务器上(数据目录 standby_data1)


                  通过 pg_basebackup 设置流复制:

                    /usr/edb/as16/bin/pg_basebackup -h localhost -U enterprisedb -p 5444 -D var/lib/edb/as16/standby_data1 -X stream -RP
                    59051/59051 kB (100%), 1/1 tablespace

                    将端口更改为 5445 并启动服务器:

                      $ usr/edb/as16/bin/pg_ctl -D var/lib/edb/as16/standby_data1 start
                      LOG:  redirecting log output to logging collector process
                      HINT:  Future log output will appear in directory "log".
                      done
                      server started

                      检查是否处于恢复模式:

                        $ usr/edb/as16/bin/psql -d edb -p 5445
                        psql (16.3.0)
                        Type "help" for help.


                        edb=# select pg_is_in_recovery();
                         pg_is_in_recovery 
                        -------------------
                         t
                        (1 row)


                        edb=# \q


                        1.3 在订阅服务器上(数据目录 logical_data)


                        初始化一个空的数据目录:

                          /usr/edb/as16/bin/initdb -D var/lib/edb/as16/logical_data

                          将端口更改为 5446 并启动服务器:

                            $ usr/edb/as16/bin/pg_ctl -D /var/lib/edb/as16/logical_data start
                            LOG:  redirecting log output to logging collector process
                            HINT:  Future log output will appear in directory "log".
                            done
                            server started

                            现在,我们在此服务器上运行了 3 个 Postgres 实例。Standby 正在从 Primary 进行复制,而 Subscriber 实例仍为空:

                              -bash-4.2$ ps -ef | grep post
                              root       1504      1  0 Jun09 ?        00:00:00 /usr/libexec/postfix/master -w
                              postfix    1520   1504  0 Jun09 ?        00:00:00 qmgr --t unix -u
                              enterpr+  11361      1  0 01:22 ?        00:00:00 /usr/edb/as16/bin/edb-postgres -D /var/lib/edb/as16/data
                              enterpr+  11362  11361  0 01:22 ?        00:00:00 postgres: logger 
                              enterpr+  11363  11361  0 01:22 ?        00:00:00 postgres: checkpointer 
                              enterpr+  11364  11361  0 01:22 ?        00:00:00 postgres: background writer 
                              enterpr+  11366  11361  0 01:22 ?        00:00:00 postgres: walwriter 
                              enterpr+  11367  11361  0 01:22 ?        00:00:00 postgres: autovacuum launcher 
                              enterpr+  11368  11361  0 01:22 ?        00:00:00 postgres: dbms_aq launcher 
                              enterpr+  11369  11361  0 01:22 ?        00:00:00 postgres: logical replication launcher 
                              enterpr+  11467      1  0 01:24 ?        00:00:00 /usr/edb/as16/bin/edb-postgres -D /var/lib/edb/as16/standby_data1
                              enterpr+  11468  11467  0 01:24 ?        00:00:00 postgres: logger 
                              enterpr+  11469  11467  0 01:24 ?        00:00:00 postgres: checkpointer 
                              enterpr+  11470  11467  0 01:24 ?        00:00:00 postgres: background writer 
                              enterpr+  11471  11467  0 01:24 ?        00:00:00 postgres: startup recovering 000000010000000000000007
                              enterpr+  11472  11467  0 01:24 ?        00:00:01 postgres: walreceiver streaming 0/7000148
                              enterpr+  11473  11361  0 01:24 ?        00:00:00 postgres: walsender enterprisedb 192.168.84.9(33466) streaming 0/7000148
                              postfix   12389   1504  0 02:15 ?        00:00:00 pickup --t unix -u
                              enterpr+  13749      1  0 03:43 ?        00:00:00 /usr/edb/as16/bin/edb-postgres -D /var/lib/edb/as16/logical_data
                              enterpr+  13750  13749  0 03:43 ?        00:00:00 postgres: logger 
                              enterpr+  13751  13749  0 03:43 ?        00:00:00 postgres: checkpointer 
                              enterpr+  13752  13749  0 03:43 ?        00:00:00 postgres: background writer 
                              enterpr+  13754  13749  0 03:43 ?        00:00:00 postgres: walwriter 
                              enterpr+  13755  13749  0 03:43 ?        00:00:00 postgres: autovacuum launcher 
                              enterpr+  13756  13749  0 03:43 ?        00:00:00 postgres: dbms_aq launcher 
                              enterpr+  13757  13749  0 03:43 ?        00:00:00 postgres: logical replication launcher 
                              enterpr+  13763  11582  0 03:44 pts/0    00:00:00 grep --color=auto post
                              -bash-4.2

                              将主数据库的全局转储并还原到这里。确保在执行此命令之前调整 pg_hba.conf 文件:

                                /usr/edb/as16/bin/pg_dumpall -h localhost -5444 -U enterprisedb -| /usr/edb/as16/bin/psql -d edb -h localhost -5446 -U enterprisedb
                                SET
                                SET
                                SET
                                ALTER PROFILE
                                ERROR:  role "enterprisedb" already exists
                                ALTER ROLE
                                CREATE ROLE
                                ALTER ROLE
                                CREATE ROLE
                                ALTER ROLE

                                使用备用服务器作为源创建订阅:

                                  $ /usr/edb/as16/bin/psql -d edb -p 5446
                                  psql (16.3.0)
                                  Type "help" for help.
                                  edb=
                                  edb=# create subscription testsub connection 'dbname=edb host=localhost port=5445 user=pubuser password=edb' publication testpub;
                                  NOTICE:  created replication slot "testsub" on publisher
                                  CREATE SUBSCRIPTION
                                  edb=#  
                                  edb=# select * from pg_subscription;
                                  -[ RECORD 1 ]-------+-----------------------------------------------------------------
                                  oid                 | 16399
                                  subdbid             | 15239
                                  subskiplsn          | 0/0
                                  subname             | testsub
                                  subowner            | 10
                                  subenabled          | t
                                  subbinary           | f
                                  substream           | f
                                  subtwophasestate    | d
                                  subdisableonerr     | f
                                  subpasswordrequired | t
                                  subrunasowner       | f
                                  subconninfo         | dbname=edb host=192.168.84.9 port=5445 user=pubuser password=edb
                                  subslotname         | testsub
                                  subsynccommit       | off
                                  subpublications     | {testpub}
                                  suborigin           | any

                                  如果此过程尚未立即完成,可能是因为备用服务器仍在等待从主服务器同步数据。在这种情况下,可以在主服务器上调用 pg_log_standby_snapshot() 函数,以刷新备用服务器上的复制状态,从而使其他复制命令能够在备用服务器上执行。

                                  在主服务器上:

                                    $ /usr/edb/as16/bin/psql -d 5444 -d edb
                                    psql (16.3.0)
                                    Type "help" for help.


                                    edb=
                                    edb=# select pg_log_standby_snapshot();
                                    pg_log_standby_snapshot 
                                    -------------------------
                                     0/70022B8
                                    (1 row)


                                    edb=


                                    二、 这种方法的优势


                                    备用服务器上的几项强大功能,包括:

                                    • 创建逻辑复制槽的能力

                                    • 发起逻辑解码的能力

                                    • 在备用服务器上订阅更改的能力

                                    • 在故障转移后仍能保持逻辑复制槽的能力


                                    三、 更新现有备用服务器以支持逻辑复制的能力


                                    将备用服务器用作逻辑复制订阅者的源是一个无缝的过程,只需要进行一些调整:

                                    • 启用 hot_standby_feedback = on;

                                    • 使用物理复制槽从上游复制数据到备用服务器;

                                    • 在主服务器上调用 pg_log_standby_snapshot(),确保订阅者在创建到备用服务器的订阅时不会停滞。


                                    关于公司

                                    感谢您关注新智锦绣科技(北京)有限公司!作为 Elastic 的 Elite 合作伙伴及 EnterpriseDB 在国内的唯一代理和服务合作伙伴,我们始终致力于技术创新和优质服务,帮助企业客户实现数据平台的高效构建与智能化管理。无论您是关注 Elastic 生态系统,还是需要 EnterpriseDB 的支持,我们都将为您提供专业的技术支持和量身定制的解决方案。


                                    欢迎关注我们,获取更多技术资讯和数字化转型方案,共创美好未来!

                                    Elastic 微信群

                                    EDB 微信群


                                    发现“分享”“赞”了吗,戳我看看吧


                                    文章转载自新智锦绣,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                    评论