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

PostgreSQL V12中的流复制配置

作者:黄凯瑞    翻译:魏波

黄凯瑞

多学科的软件开发人员,专门从事C C ++软件开发,网络安全,嵌入式软件,防火墙和IT基础结构。


1

概述


PostgreSQL 12被认为是一个主要更新,包括对性能的重大改进分区增强索引改进优化执行计划逻辑等。主要变化之一是删除文件recovery.conf。因此,设置流复制群集的过程已更改,在本博客中,我将演示如何在PG12中正确设置流复制。

流复制设置需要一个主群集和一个或多个从群集,这些群集将通过流传输由主生成的已归档WAL文件来复制插入到从群集数据库中。主服务器和从服务器可以驻留在通过网络连接的不同计算机上,但是在本博客中,我们将使用一个主服务器和一个从服务器设置,并且两者都将在具有不同端口号的同一台计算机上运行。

本博客中说明的过程基于Postgres版本12,该版本是从在Ubuntu 18.04上运行的源构建的

2

主数据库群集设置


使用initdb工具创建一个主数据库集群:

    $ initdb home/caryh/streaming-replication/db-master
    $ cd /home/caryh/streaming-replication

    / home caryh streaming-replication是我们将在此Blog中创建的所有数据库集群的根文件夹,由于上述命令,将在此处创建db-master目录。让我们修改默认的postgreql.conf并启用以下几个重要的配置选项,以进行流复制设置。

      ############# db-master/postgresql.conf #############
      wal_level = replica
      archive_mode = on
      max_wal_senders = 10
      wal_keep_segments = 10
      hot_standby = on
      archive_command = 'test ! -f home/caryh/streaming-replication/archivedir/%f && cp %p home/caryh/streaming-replication/archivedir/%f'
      port = 5432
      wal_log_hints = on

      上面的配置使Postgres在完成写入完整的WAL文件块时或发出pg_basebackup命令时,可以将WAL文件归档在目录/ home caryh streaming-replication archivedir /中。其中在archive_command参数中使用的%f和%p,其含义为f将替换为目标WAL文件的文件名,而%p将替换为目标WAL文件的路径。

      进行设置archive_command以确保将WAL文件归档到从属群集可以访问的位置,这一点非常重要。

      请注意,wal_log_hints必须启用pg_rewind工具才能使其正常工作。我们将在下一篇博客文章中讨论有关pg_rewind的更多信息。

      检查客户端身份验证文件db-master/pg_hba.conf,并确保主群集允许从从群集远程复制连接。就我而言,我的主服务器和从服务器都将在同一主机上运行,因此我将保留环回IP地址。如果您的从属群集位于另一台计算机上,请确保将正确的环回地址替换为正确的地址。

        ############# db-master/pg_hba.conf #############
        # Allow replication connections from 127.0.0.1, by a user with the replication privilege.
        # TYPE DATABASE USER ADDRESS METHOD
        host    replication     all             127.0.0.1/32            trust

        让我们继续,使用上述配置文件启动master数据库集群,创建具有复制权限的超级用户,以及一个名为clusterdb的数据库。

          $ pg_ctl -D db-master start
          $ createuser cary -s --replication
          $ createdb clusterdb

          将一些测试数据插入主群集。为简单起见,我们将向test_table插入100个整数。

            $ psql -d clusterdb -U cary -c "CREATE TABLE test_table(x integer)"
            CREATE TABLE
            $ psql -d clusterdb -U cary -c "INSERT INTO test_table(x) SELECT y FROM generate_series(1, 100) a(y)"
            INSERT 0 100
            $ psql -d clusterdb -U cary -c "SELECT count(*) from test_table"
            count
            -------
            100
            (1 row)


            3

            从数据库集群设置


            设置从属群集的目的是对当前主服务器进行备份并将其设置为备用服务器,这意味着它将从主服务器流式传输WAL文件更新并执行数据复制。

            Postgres提供了几种工具和方法来执行物理数据库备份。诸如pg_start_backup('label')pg_stop_backup()在较早的Postgres版本中很常见。在此博客中,我们将使用更新且更简单的非排他性pg_basebackup工具执行备份。两种方法都有优点和缺点,此内容不在本博客的讨论范围之内。本文在这两种方法上提供了很好的解释:

            https://www.cybertec-postgresql.com/zh-CN/exclusive-backup-deprecated-what-now/

            让我们使用pg_basebackup创建从集群。

              $ pg_basebackup -h 127.0.0.1 -U cary -p 5432 -D db-slave -P -Xs -R
              31373/31373 kB (100%), 1/1 tablespace

              其中:

              -h是主群集的IP 

              -U是允许进行复制的用户名

              -p是正在运行的主群集的端口号

              -D是我们要在其中设置从数据库群集的目录

              -P显示进度

              -Xs选择WAL流方法

              -R编写一个recovery.conf文件。

              此步骤与以前的PG版本有所不同。-R命令将不再在db-slave目录中输出recovery.conf文件。

                $ ls db-slave
                backup_label pg_dynshmem pg_multixact pg_snapshots pg_tblspc pg_xact
                base pg_hba.conf pg_notify pg_stat pg_twophase postgresql.auto.conf
                global pg_ident.conf pg_replslot pg_stat_tmp PG_VERSION postgresql.conf
                pg_commit_ts  pg_logical     pg_serial     pg_subtrans   pg_wal       standby.signal

                旧的recovery.conf文件的内容将移至postgresql.confpostgresql.auto.conf

                让我们先检查一下db-slave/postgresql.auto.conf,我们将看到pg_basebackup已经为我们创建了primary_conninfo。该行以前位于recovery.conf中,它告诉从群集应从何处

                  以及如何从主群集中流式传输。确保postgresql.auto.conf中存在此行。
                  ############# db-slave/postgresql.auto.conf #############
                  # Do not edit this file manually!
                  # It will be overwritten by the ALTER SYSTEM command.
                  primary_conninfo = 'user=cary passfile=''/home/caryh/.pgpass'' host=127.0.0.1 port=5432 sslmode=prefer sslcompression=0 gssencmode=disable target_session_attrs=any'

                  让我们检查db-slave/postgresql.conf并更新一些参数。

                    ############# db-slave/postgresql.conf #############
                    wal_level = replica
                    archive_mode = on
                    max_wal_senders = 10
                    wal_keep_segments = 10
                    hot_standby = on
                    archive_command = 'test ! -f /home/caryh/streaming-replication/archivedir/%f && cp %p /home/caryh/streaming-replication/archivedir/%f'
                    wal_log_hints = on
                    port = 5433
                    restore_command = 'cp /home/caryh/streaming-replication/archivedir/%f %p'
                    archive_cleanup_command = 'pg_archivecleanup /home/caryh/streaming-replication/archivedir %r'

                    由于db-slave/postgresql.conf是通过pg_basebackup从主群集直接复制的,因此我们需要将其更改为port与主端口不同的端口(在本例中为5433),因为两者都在同一台计算机上运行。我们将需要填restore_commandarchive_cleanup_command从属群集知道如何获取已归档的WAL文件以进行流传输。这两个参数曾经在recovery.conf中定义PG12将其移至postgresql.conf中。

                    请注意,在db-slave目录中,standby.signal将自动创建一个新文件,pg_basebackup指示该从集群将以standby模式运行。该文件standby.signalPG12中的新增功能,用以替代standby_mode = 'on',以前在文件recovery.conf中定义。如果此文件不存在,请确保通过以下方式创建它:

                      $ touch db-slave/standby.signal

                      现在,让我们启动从集群:

                        $ pg_ctl -D db-slave start

                        4

                        验证流复制设置


                        一旦主集群和从集群都已设置并运行,我们应该从ps -ef命令中看到一些后端进程已启动实现复制,即walsenderwalreceiver

                          $ ps -ef | grep postgres
                          caryh 12782 2921 0 16:12 ? 00:00:00 /usr/local/pgsql/bin/postgres -D db-master
                          caryh 12784 12782 0 16:12 ? 00:00:00 postgres: checkpointer
                          caryh 12785 12782 0 16:12 ? 00:00:00 postgres: background writer
                          caryh 12786 12782 0 16:12 ? 00:00:00 postgres: walwriter
                          caryh 12787 12782 0 16:12 ? 00:00:00 postgres: autovacuum launcher
                          caryh 12788 12782 0 16:12 ? 00:00:00 postgres: archiver last was 000000010000000000000002.00000028.backup
                          caryh 12789 12782 0 16:12 ? 00:00:00 postgres: stats collector
                          caryh 12790 12782 0 16:12 ? 00:00:00 postgres: logical replication launcher
                          caryh 15702 2921 0 17:06 ? 00:00:00 /usr/local/pgsql/bin/postgres -D db-slave
                          caryh 15703 15702 0 17:06 ? 00:00:00 postgres: startup recovering 000000010000000000000003
                          caryh 15708 15702 0 17:06 ? 00:00:00 postgres: checkpointer
                          caryh 15709 15702 0 17:06 ? 00:00:00 postgres: background writer
                          caryh 15711 15702 0 17:06 ? 00:00:00 postgres: stats collector
                          caryh 15713 15702 0 17:06 ? 00:00:00 postgres: walreceiver streaming 0/3000148
                          caryh 15714 12782 0 17:06 ? 00:00:00 postgres: walsender cary 127.0.0.1(59088) streaming 0/3000148
                          caryh    15728 10962  0 17:06 pts/5    00:00:00 grep --color=auto post

                          我们还可以通过向主集群发出查询来详细检查复制状态:

                            $ psql -d clusterdb -U cary -c "select * from pg_stat_replication;" -x -p 5432
                            -[ RECORD 1 ]----+------------------------------
                            pid | 15714
                            usesysid | 16384
                            usename | cary
                            application_name | walreceiver
                            client_addr | 127.0.0.1
                            client_hostname |
                            client_port | 59088
                            backend_start | 2019-10-29 17:06:49.072082-07
                            backend_xmin |
                            state | streaming
                            sent_lsn | 0/3000148
                            write_lsn | 0/3000148
                            flush_lsn | 0/3000148
                            replay_lsn | 0/3000148
                            write_lag |
                            flush_lag |
                            replay_lag |
                            sync_priority | 0
                            sync_state | async
                            reply_time       | 2019-10-29 17:10:09.515563-07

                            最后,我们可以将其他数据插入主群集,并验证从属群集是否也更新了数据。

                              # Query slave cluster
                              $ psql -d clusterdb -U cary -c "SELECT count(*) from test_table" -p 5433
                              count
                              -------
                              100
                              (1 row)
                              # Query master cluster
                              $ psql -d clusterdb -U cary -c "SELECT count(*) from test_table" -p 5432
                              count
                              -------
                              100
                              (1 row)
                              # Insert more data to master cluster
                              $ psql -d clusterdb -U cary -c "INSERT INTO test_table(x) SELECT y FROM generate_series(1, 100) a(y)" -p 5432
                              INSERT 0 100
                              # Query slave cluster again
                              psql -d clusterdb -U cary -c "SELECT count(*) from test_table" -p 5433
                              count
                              -------
                              200
                              (1 row)

                              现在,主群集和从群集都已同步。


                              5

                              设置复制槽


                              前面的步骤说明了如何正确设置主群集和从群集之间的流复制。但是,在某些情况下,由于某些原因,从属服务器可能会断开连接,从而导致时间延长,并且当某些未复制的WAL文件被回收或从wal_keep_segments参数控制的主群集中删除时,可能无法与主服务器进行复制。

                              复制槽确保主服务器可以为所有从服务器保留足够的WAL段,防止主服务器删除可能导致从服务器上发生恢复冲突的行。

                              让我们在主集群上创建一个复制槽slave

                                $ psql -d clusterdb -U cary -c "select * from pg_create_physical_replication_slot('slave')" -p 5432
                                slot_name | lsn
                                -----------+-----
                                slave |
                                (1 row)
                                $ psql -d clusterdb -U cary -c "select * from pg_replication_slots" -x -p 5432
                                -[ RECORD 1 ]-------+---------
                                slot_name | slave
                                plugin |
                                slot_type | physical
                                datoid |
                                database |
                                temporary | f
                                active | f
                                active_pid |
                                xmin |
                                catalog_xmin |
                                restart_lsn |
                                confirmed_flush_lsn | 

                                我们刚刚在master上创建了复制槽slave,该复制槽当前未处于活动状态(active = f)。

                                让我们修改从属服务器postgresql.conf并使其连接到主服务器的复制槽

                                  ############# db-slave/postgresql.conf #############
                                  primary_slot_name = 'slave'


                                  请注意,这个参数primary_slot_name我们也曾经定义recovery.confPG12移至postgresql.conf中。更改后,我们需要重新启动从节点

                                    $ pg_ctl -D db-slave stop
                                    $ pg_ctl -D db-slave start

                                    如果一切正常,则检查主服务器上的复制槽的插槽状态应为活动状态。

                                      $ psql -d clusterdb -U cary -c "select * from pg_replication_slots" -x -p 5432
                                      -[ RECORD 1 ]-------+----------
                                      slot_name | slave
                                      plugin |
                                      slot_type | physical
                                      datoid |
                                      database |
                                      temporary | f
                                      active | t
                                      active_pid | 16652
                                      xmin |
                                      catalog_xmin |
                                      restart_lsn | 0/3003B98
                                      confirmed_flush_lsn |


                                      6

                                      总结

                                      在此博客中,我们讨论了如何PG12中设置流复制群集,其中从旧版本更改了几个步骤,尤其是删除了recovery.conf

                                      这是与复制设置相关更改的简短列表,这些更改已从 recovery.conf

                                      · restore_command =>移至 postgresql.conf

                                      · recovery_target_timeline =>已移至 postgresql.conf

                                      · Standby_mode =>替换为 standby.signal

                                      · primary_conninfo =>移至postgresql.confpostgresql.auto.conf

                                      · archive_cleanup_command =>移至 postgresql.conf

                                      · primary_slot_name =>移至 postgresql.conf

                                      欢迎投稿



                                              中国开源软件推进联盟PostgreSQL分会,欢迎大家积极投稿,向PGer分享自己的实践经验、心得体会,共建PG中国生态。

                                      投稿邮箱:

                                      partner@postgresqlchina.com


                                      最后修改时间:2019-12-12 09:30:22
                                      文章转载自开源软件联盟PostgreSQL分会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                      评论