天天看点

PostgreSQL reload配置的动作反馈与源码分析

digoal

2016-09-01

postgresql , reload , 配置

postgresql数据库的配置文件中,有一些配置项是支持reload的,但是如果配置写错了,reload时怎么知道呢?

reload其实是通过给postmaster进程发sighup信号来实现的。

通过pg_ctl或者kill或者pg_reload_conf()函数都可以发信号。

postmaster收到这个信号之后,会调用sighup_handler,处理一堆事务,包括重载配置文件(包括postgresql.conf, pg_hba.conf, pg_ident.conf),以及调用一些处理函数。

从代码来看,发起reload的进程,并不知道reload的结果,因为信号发完就了事了。

src/backend/utils/adt/misc.c

postmaster进程收到sighup信号后的处理,如下

src/backend/postmaster/postmaster.c

我们关心的是重载配置文件的几个调用

postgresql.conf 配置文件重载的代码如下,如果有错误,会调用ereport,输出到日志。

重载pg_hba.conf的代码,如果有错误也会输出,但是同样是postmaster进程的输出,而不是用户进程。

我们可以看到,如果重载异常,ereport调用是postmaster发出的,发送sighup信号的进程(即与用户交互的backend process)收不到这个告警。

所以,用户可以查看数据库日志的方式,了解重载配置文件是否异常。

目前,不管reload有没有成功,都会更新reload时间,所以通过pg_conf_load_time获取到的是接收到sighup信号的时间,并不能代表最后的成功reload时间

但是backend process怎么样才能知道reload异常了呢?

因为backend process发完信号就返回了,所以只要信号发成功就可以,至于reload它才不管呢,那么postmaster怎么把问题反馈给backend process呢?

我想到一个思路是异步消息,我们知道postgresql是支持异步消息的,我以前写过一些文档介绍异步消息, 例如

《postgresql notify/listen like esb》

<a href="https://yq.aliyun.com/articles/14606">https://yq.aliyun.com/articles/14606</a>

《postgresql 的小玩具, async notification as a chat group》

<a href="https://yq.aliyun.com/articles/81">https://yq.aliyun.com/articles/81</a>

其实greenplum在一些管理手段中也使用了异步消息,用于传递一些状态信息。

postgresql其实也可以这样做:

1. 后台进程调用pg_reload_conf(),并且监听一个channel(例如我们固定命名为reload channel)。

2. 信号发完,postmaster开始处理信号。

3. postmaster在解析配置文件,或者reload配置文件时,如果遇到错误,除了触发ereport之外,同时将异步消息通知到对应的channel。

4. 这样的话,只要backend process不退出,就能收到来自postmaster的通知,知道reload是否异常。

<a href="http://info.flagcounter.com/h9v1">count</a>

继续阅读