我们有一个主从复制配置如下。
在主人身上:
postgresql.conf
具有如下配置的复制(为简洁起见,引用了注释行):
max_wal_senders = 1
wal_keep_segments = 8
在奴隶上:
与主人相同postgresql.conf
。 recovery.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频道的一些分析和帮助,我得出结论,奴隶无法跟上主人。我提出的解决方案如下。
在主人身上:
max_wal_senders=5
wal_keep_segments=4000
。是的,我知道它非常高,但我想监控情况,看看会发生什么。我有主人的空间。在奴隶上:
pg_hba.conf pg_ident.conf postgresql.conf recovery.conf
)rm -rf /var/lib/pgsql/9.3/data/*
)。这似乎是pg_basebackup
。pg_basebackup -h master -D /var/lib/pgsql/9.3/data --username=replication --password
我错过了什么吗?有没有更好的方法让奴隶最新而不必重新加载所有数据?
非常感谢任何帮助。
答案 0 :(得分:23)
处理WAL的streaming 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个分段/小时的备份。