PostgreSQL 12 中配置流复制Streaming Replication
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/中其中f将替换为目标WAL文件的文件名而p将替换为目标WAL文件的路径。进行设置archive_command以确保将WAL文件归档到从属群集可以访问的位置时这一点非常重要。另外wal_log_hints必须启用pg_rewind工具才能使其正常工作。我们将在下一篇博客文章中讨论有关pg_rewind的更多信息。检查客户端身份验证文件db-master/pg_hba.conf并确保主群集允许从从群集远程复制连接。就我而言我的主服务器和从服务器都将在同一主机上运行因此我将保留loopback IP地址。如果您的从属群集位于另一台计算机上请确保将正确的loopback 地址替换为正确的地址。############# 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将一些测试数据插入主群集。为简单起见我们将向插入100个整数test_table。$ 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_basebackupfronend工具执行备份$ 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.conf和postgresql.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 usercary passfile/home/caryh/.pgpass host127.0.0.1 port5432 sslmodeprefer sslcompression0 gssencmodedisable target_session_attrsany让我们检查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_command和archive_cleanup_command因此从属群集知道如何获取已归档的WAL文件以进行流传输。这两个参数曾经在PG12中定义recovery.conf并移至其中postgresql.conf。请注意在db-slave目录中standby.signal将自动创建一个新文件pg_basebackup以指示该从集群将以standby模式运行。该standby.signal文件是PG12中的新增功能用以替代standby_mode on’以前在中定义的文件recovery.conf。如果此文件不存在请确保通过以下方式创建它$ touch db-slave/standby.signal现在让我们启动从集群$ pg_ctl -D db-slave start4.验证流复制设置一旦主集群和从集群都已设置并运行我们应该从ps -ef命令中看到一些后端进程已启动以实现复制即walsender和walreceiver。$ 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 --colorauto 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我们也曾经在PG12中定义recovery.conf并移至postgresql.confPG12中。更改后我们需要重新启动从站。$ 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.confrestore_command 移至 postgresql.confrecovery_target_timeline 已移至 postgresql.confStandby_mode 替换为 standby.signalprimary_conninfo 移至postgresql.conf或postgresql.auto.confarchive_cleanup_command 移至 postgresql.confprimary_slot_name 移至 postgresql.conf