如何修复无法跟上主服务器的 PostgreSQL 9.3 从服务器?
How do I fix a PostgreSQL 9.3 Slave that Cannot Keep Up with the Master?
我们有一个主从复制配置如下。
关于高手:
postgresql.conf
复制配置如下(为简洁起见删除了注释行):
max_wal_senders = 1
wal_keep_segments = 8
从机上:
与 master 相同 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 频道上进行了一些分析和帮助后,我得出的结论是slave 跟不上master。我提出的解决方案如下。
关于高手:
- 设置
max_wal_senders=5
- 设置
wal_keep_segments=4000
。是的,我知道它非常高,但我想监控情况并看看会发生什么。我在master上有空
从机上:
- 将配置文件保存在数据目录中(即
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
我错过了什么吗?有没有更好的方法使从站更新 w/o 必须重新加载所有数据?
非常感谢任何帮助。
正如 Ben Grimm 在评论中所建议的那样,这是一个确保将段设置为最大可能值以允许从机赶上的问题。
处理WAL for 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"'
当slave不能直接从master拉取WAL段时,它会尝试使用restore_command
加载它。您可以使用 archive_cleanup_command
设置将从站配置为自动删除段。
如果从服务器遇到主服务器和存档都缺少它需要的下一个 WAL 段的情况,将无法一致地恢复数据库。 唯一 合理的选择是清理服务器并从新的 pg_basebackup
重新启动。
实际上要恢复,您不必丢弃整个数据库并从头开始。由于 master 有最新的二进制文件,您可以执行以下操作来恢复 slave 并使它们恢复同步:
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. slave 必须被 service stop
拒绝
2.master会因为查询pg_start_backup
转为只读
3. master 可以继续提供只读查询
4. 在步骤结束时带回奴隶
我在产品中这样做了,它对我来说很完美。
slave 和 master 是同步的,没有数据丢失。
您可以为 postgress 配置 replication slots
以保留此类插槽中提到的副本的 WAL 段。
在 https://www.percona.com/blog/2018/11/30/postgresql-streaming-physical-replication-with-slots/
阅读更多内容
在主服务器上 运行
SELECT pg_create_physical_replication_slot('standby_slot');
在从属服务器上将下一行添加到 recovery.conf
primary_slot_name = 'standby_slot'
如果 keep_wal_segments
设置太低,您将收到该错误。
当您设置 keep_wal_segments
的值时,请考虑 "How long is the pg_basebackup
taking?"
请记住,分段大约每 5 分钟生成一次,因此如果备份需要一个小时,您至少需要保存 12 个分段。在 2 小时,您需要 24,等等。我会将值设置为大约 12.2 segments/hour 备份。
我们有一个主从复制配置如下。
关于高手:
postgresql.conf
复制配置如下(为简洁起见删除了注释行):
max_wal_senders = 1
wal_keep_segments = 8
从机上:
与 master 相同 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 频道上进行了一些分析和帮助后,我得出的结论是slave 跟不上master。我提出的解决方案如下。
关于高手:
- 设置
max_wal_senders=5
- 设置
wal_keep_segments=4000
。是的,我知道它非常高,但我想监控情况并看看会发生什么。我在master上有空
从机上:
- 将配置文件保存在数据目录中(即
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
我错过了什么吗?有没有更好的方法使从站更新 w/o 必须重新加载所有数据?
非常感谢任何帮助。
正如 Ben Grimm 在评论中所建议的那样,这是一个确保将段设置为最大可能值以允许从机赶上的问题。
处理WAL for 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"'
当slave不能直接从master拉取WAL段时,它会尝试使用
restore_command
加载它。您可以使用archive_cleanup_command
设置将从站配置为自动删除段。
如果从服务器遇到主服务器和存档都缺少它需要的下一个 WAL 段的情况,将无法一致地恢复数据库。 唯一 合理的选择是清理服务器并从新的 pg_basebackup
重新启动。
实际上要恢复,您不必丢弃整个数据库并从头开始。由于 master 有最新的二进制文件,您可以执行以下操作来恢复 slave 并使它们恢复同步:
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. slave 必须被 service stop
拒绝
2.master会因为查询pg_start_backup
转为只读
3. master 可以继续提供只读查询
4. 在步骤结束时带回奴隶
我在产品中这样做了,它对我来说很完美。 slave 和 master 是同步的,没有数据丢失。
您可以为 postgress 配置 replication slots
以保留此类插槽中提到的副本的 WAL 段。
在 https://www.percona.com/blog/2018/11/30/postgresql-streaming-physical-replication-with-slots/
阅读更多内容在主服务器上 运行
SELECT pg_create_physical_replication_slot('standby_slot');
在从属服务器上将下一行添加到 recovery.conf
primary_slot_name = 'standby_slot'
如果 keep_wal_segments
设置太低,您将收到该错误。
当您设置 keep_wal_segments
的值时,请考虑 "How long is the pg_basebackup
taking?"
请记住,分段大约每 5 分钟生成一次,因此如果备份需要一个小时,您至少需要保存 12 个分段。在 2 小时,您需要 24,等等。我会将值设置为大约 12.2 segments/hour 备份。