如何修复无法跟上Master的PostgreSQL 9.3 Slave?

时间:2015-01-28 20:11:33

标签: postgresql replication redhat

我们有一个主从复制配置如下。

在主人身上:

postgresql.conf具有如下配置的复制(为简洁起见,引用了注释行):

max_wal_senders = 1            
wal_keep_segments = 8          

在奴隶上:

与主人相同postgresql.confrecovery.conf看起来像这样:

standby_mode = 'on'
primary_conninfo = 'host=master1 port=5432 user=replication password=replication'
trigger_file = '/tmp/postgresql.trigger.5432'

当最初设置时,我们执行了一些简单的测试并确认复制正常。但是,当我们进行初始数据加载时,只有部分数据进入了从属数据库。

Slave的日志现在填充了如下所示的消息:

< 2015-01-23 23:59:47.241 EST >LOG:  started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:47.241 EST >FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000F00000052 has already been removed

< 2015-01-23 23:59:52.259 EST >LOG:  started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:52.260 EST >FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000F00000052 has already been removed

< 2015-01-23 23:59:57.270 EST >LOG:  started streaming WAL from primary at F/52000000 on timeline 1
< 2015-01-23 23:59:57.270 EST >FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000F00000052 has already been removed

经过对#postgresql IRC频道的一些分析和帮助,我得出结论,奴隶无法跟上主人。我提出的解决方案如下。

在主人身上:

  1. 设置max_wal_senders=5
  2. 设置wal_keep_segments=4000。是的,我知道它非常高,但我想监控情况,看看会发生什么。我有主人的空间。
  3. 在奴隶上:

    1. 将配置文件保存在数据目录中(即pg_hba.conf pg_ident.conf postgresql.conf recovery.conf
    2. 清除数据目录(rm -rf /var/lib/pgsql/9.3/data/*)。这似乎是pg_basebackup
    3. 所要求的
    4. 运行以下命令: pg_basebackup -h master -D /var/lib/pgsql/9.3/data --username=replication --password
    5. 我错过了什么吗?有没有更好的方法让奴隶最新而不必重新加载所有数据?

      非常感谢任何帮助。

5 个答案:

答案 0 :(得分:23)

处理WALstreaming replication的两个重要选项:

  • wal_keep_segments应该设置得足够高,以便让奴隶在合理的滞后后赶上(例如高更新量,奴隶离线等等)。

  • archive_mode启用WAL归档,可用于恢复早于wal_keep_segments提供的文件。从属服务器只需要一种方法来检索WAL段。 NFS是最简单的方法,但是从scp到http到磁带的任何东西都可以工作,只要它可以编写脚本。

    # on master
    archive_mode = on
    archive_command = 'cp %p /path_to/archive/%f' 
    
    # on slave
    restore_command = 'cp /path_to/archive/%f "%p"'
    

    当从属设备无法直接从主设备中拉出WAL段时,它将尝试使用restore_command加载它。您可以将从站配置为使用archive_cleanup_command设置自动删除段。

如果从属设备遇到主设备和存档都缺少所需的下一个WAL段的情况,则无法一致地恢复数据库。然后,仅 合理的选项是擦除服务器并从新的pg_basebackup重新开始。

答案 1 :(得分:0)

正如Ben Grimm在评论中所建议的那样,这是一个确保将段设置为最大可能值以允许从站赶上的问题。

答案 2 :(得分:0)

实际上,要恢复,您不必删除整个数据库并从头开始。由于主服务器具有最新的二进制文件,因此您可以执行以下操作来恢复从服务器并将其恢复同步:

psql -c "select pg_start_backup('initial_backup');"
rsync -cva --inplace --exclude=*pg_xlog* <data_dir> slave_IP_address:<data_dir>
psql -c "select pg_stop_backup();"

注意:
1.必须通过service stop
关闭从属 2.由于查询pg_start_backup
主机将变为只读 3.主服务器可以继续提供只读查询
4.在步骤结束时将奴隶带回

我是在产品中这样做的,它对我来说非常完美。 从机和主机同步,没有数据丢失。

答案 3 :(得分:0)

您可以为后退配置replication slots,以保留该插槽中提到的副本的WAL段。

更多{@ {3}}

在主服务器上运行

SELECT pg_create_physical_replication_slot('standby_slot'); 

在从属服务器上,添加到recovery.conf下一行

primary_slot_name = 'standby_slot'

答案 4 :(得分:0)

如果keep_wal_segments设置太低,则会收到该错误。 当您为keep_wal_segments设置值时,请考虑“ pg_basebackup需要花费多长时间?”

请记住,分段大约每5分钟生成一次,因此,如果备份需要一个小时,则至少需要保存12个分段。 2小时后,您需要24个,依此类推。我将值设置为大约12.2个分段/小时的备份。