常见问题
Module:
Categories:
PGSQL初始化失败:ABORT due to postgres exists
这意味着正在初始化的 PostgreSQL 实例已经存在了, 将 pg_clean
设置为 true
,并将 pg_safeguard
设置为 false
,就可以在执行 pgsql.yml
期间强制清理现存实例。
如果 pg_clean
为 true
(并且 pg_safeguard
也为 false
),pgsql.yml
剧本将会移除现有的 pgsql 数据并重新初始化为新的,这使得这个剧本真正幂等。
你可以通过使用一个特殊的任务标签 pg_purge
来强制清除现有的 PostgreSQL 数据,这个标签任务会忽略 pg_clean
和 pg_safeguard
的设置,所以非常危险。
./pgsql.yml -t pg_clean # 优先考虑 pg_clean 和 pg_safeguard
./pgsql.yml -t pg_purge # 忽略 pg_clean 和 pg_safeguard
PGSQL初始化失败:ABORT due to pg_safeguard enabled
这意味着正准备清理的 PostgreSQL 实例打开了防误删保险, 禁用 pg_safeguard
以移除 Postgres 实例。
如果防误删保险 pg_safeguard
打开,那么你就不能使用 bin/pgsql-rm
和 pgsql-rm.yml
剧本移除正在运行的 PGSQL 实例了。
要禁用 pg_safeguard
,你可以在配置清单中将 pg_safeguard
设置为 false
,或者在执行剧本时使用命令参数 -e pg_safeguard=false
。
./pgsql-rm.yml -e pg_safeguard=false -l <cls_to_remove> # 强制覆盖 pg_safeguard
———————–`
PGSQL初始化失败:Fail to wait for postgres/patroni primary
这种错误信息存在多种可能,需要你 检查 Ansible,Systemd / Patroni / PostgreSQL 日志,找出真正的原因。
- 可能性1:集群配置错误,找出错误的配置项修改并应用。
- 可能性2:在部署中存在同名集群,或者之前的同名集群主节点被不正确地移除
- 可能性3:在DCS中有同名集群残留的垃圾元数据:没有正确完成下线,你可以使用
etcdctl del --prefix /pg/<cls>
来手工删除残留数据(请小心) - 可能性4:你的 PostgreSQL 或节点相关 RPM 包没有被成功安装
- 可能性5:你的 Watchdog 内核模块没有正确启用加载
- 可能性6:你在初始化数据库时指定的语言 Locale 不存在(例如,使用了 en_US.UTF8,但没有安装英文语言包或 Locale 支持)
- 如果你遇到了其他的原因,欢迎提交 Issue 或向社区求助。
PGSQL初始化失败:Fail to wait for postgres/patroni replica
存在几种可能的原因:
立即失败:通常是由于配置错误、网络问题、损坏的DCS元数据等原因。你必须检查 /pg/log
找出实际原因。
过了一会儿失败:这可能是由于源实例数据损坏。查看 PGSQL FAQ:如何在数据损坏时创建副本?
过了很长时间再超时:如果 wait for postgres replica
任务耗时 30 分钟或更长时间并由于超时而失败,这对于大型集群(例如,1TB+,可能需要几小时创建一个副本)是很常见的。
在这种情况下,底层创建副本的过程仍在进行。你可以使用 pg list <cls>
检查集群状态并等待副本赶上主节点。然后使用以下命令继续以下任务,完成完整的从库初始化:
./pgsql.yml -t pg_hba,pg_reload,pg_backup,pgbouncer,pg_vip,pg_dns,pg_service,pg_exporter,pg_register -l <problematic_replica>
如何安装其他的PostgreSQL大版本:12 - 14,以及 16beta
要安装 PostgreSQL 12 - 15,你必须在配置清单中设置 pg_version
为 12
、13
、14
或 15
,通常在集群级别配置这个参数。
pg_version: 16 # 在此模板中安装 pg 16
pg_libs: 'pg_stat_statements, auto_explain' # 从 pg 16 beta 中移除 timescaledb,因为它不可用
pg_extensions: [] # 目前缺少 pg16 扩展
在 prod.yml 43 节点生产环境仿真模板中提供了安装 12 - 16 大版本集群的示例。
详情请参考 PGSQL配置:切换大版本
如何为 PostgreSQL 启用大页/HugePage?
使用
node_hugepage_count
和node_hugepage_ratio
或/pg/bin/pg-tune-hugepage
如果你计划启用大页(HugePage),请考虑使用 node_hugepage_count
和 node_hugepage_ratio
,并配合 ./node.yml -t node_tune
进行应用。
大页对于数据库来说有利有弊,利是内存是专门管理的,不用担心被挪用,降低数据库 OOM 风险。缺点是某些场景下可能对性能由负面影响。
在 PostgreSQL 启动前,您需要分配 足够多的 大页,浪费的部分可以使用 pg-tune-hugepage
脚本对其进行回收,不过此脚本仅 PostgreSQL 15+ 可用。
如果你的 PostgreSQL 已经在运行,你可以使用下面的办法启动大页(仅 PG15+ 可用):
sync; echo 3 > /proc/sys/vm/drop_caches # 刷盘,释放系统缓存(请做好数据库性能受到冲击的准备)
sudo /pg/bin/pg-tune-hugepage # 将 nr_hugepages 写入 /etc/sysctl.d/hugepage.conf
pg restart <cls> # 重启 postgres 以使用 hugepage
如何确保故障转移中数据不丢失?
使用
crit.yml
参数模板,设置pg_rpo
为0
,或配置集群为同步提交模式。
考虑使用 同步备库 和 法定多数提交 来确保故障转移过程中的零数据丢失。
更多细节,可以参考 安全考量 - 可用性 的相关介绍。
磁盘写满了如何抢救?
如果磁盘写满了,连 Shell 命令都无法执行,rm -rf /pg/dummy
可以释放一些救命空间。
默认情况下,pg_dummy_filesize
设置为 64MB
。在生产环境中,建议将其增加到 8GB
或更大。
它将被放置在 PGSQL 主数据磁盘上的 /pg/dummy
路径下。你可以删除该文件以释放一些紧急空间:至少可以让你在该节点上运行一些 shell 脚本来进一步回收其他空间。
当集群数据已经损坏时如何创建副本?
Pigsty 在所有实例的 patroni 配置中设置了 cloneform: true
标签,标记该实例可用于创建副本。
如果某个实例有损坏的数据文件,导致创建新副本的时候出错中断,那么你可以设置 clonefrom: false
来避免从损坏的实例中拉取数据。具体操作如下
$ vi /pg/bin/patroni.yml
tags:
nofailover: false
clonefrom: true # ----------> change to false
noloadbalance: false
nosync: false
version: '15'
spec: '4C.8G.50G'
conf: 'oltp.yml'
$ systemctl reload patroni # 重新加载 Patroni 配置
PostgreSQL 监控的性能损耗如何?
一个常规 PostgreSQL 实例抓取耗时大约 200ms。抓取间隔默认为 10 秒,对于一个生产多核数据库实例来说几乎微不足道。
请注意,Pigsty 默认开启了库内对象监控,所以如果您的数据库内有数以十万计的表/索引对象,抓取可能耗时会增加到几秒。
您可以修改 Prometheus 的抓取频率,请确保一点:抓取周期应当显著高于一次抓取的时长。
如何监控一个现存的 PostgreSQL 实例?
在 PGSQL Monitor 中提供了详细的监控配置说明。
如何手工从 Prometheus 中移除 PostgreSQL 监控对象?
./pgsql-rm.yml -t prometheus -l <cls> # 将集群 'cls' 的所有实例从 prometheus 中移除
bin/pgmon-rm <ins> # 用于从 Prometheus 中移除单个实例 'ins' 的监控对象,特别适合移除添加的外部实例
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.