1、Worker
PG支持内置Worker,可以自定义伴随主进程一起启停的守护进程。
详细文档:Background Worker Processes
已经有很多例子,比如:pg_cron
2、Odyssey多线程连接池
单进程的PgBouncer有很明显的瓶颈,很多人的解决办法是多启实例,这样一来管理是个痛苦的事情。
俄罗斯Yandex出品的 Odyssey 是一个不错的替代品。
架构介绍:Odyssey architecture and internals
3、启动主函数
int main(int argc, char *argv[])
{
od_instance_t odyssey;
od_instance_init(&odyssey);
int rc = od_instance_main(&odyssey, argc, argv);
if (rc == -1) {
rc = EXIT_FAILURE;
} else {
rc = EXIT_SUCCESS;
}
od_instance_free(&odyssey);
return rc;
}
只需要告诉Odyssey配置文件在何处即可
4、GUC自定义配置
在 postgresql.conf 文件的最后,我们能看到
#------------------------------------------------------------------------------
# CUSTOMIZED OPTIONS
#------------------------------------------------------------------------------
# Add settings for extensions here
GUC参数是允许用户程序自定义的
可以把 PL/pgSQL的定义 作为例子,这里涵盖枚举、布尔、字符串,此外还支持整形、浮点。
例如我们可以定义 odyssey.config_file 用来指定配置文件位置
5、简单示范
PG_MODULE_MAGIC;
char *od_config_file;
void
_PG_init(void)
{
BackgroundWorker worker;
DefineCustomStringVariable("odyssey.config_file",
略 ...
);
worker.bgw_flags = 0;
worker.bgw_start_time = BgWorkerStart_RecoveryFinished;
worker.bgw_restart_time = 1;
worker.bgw_main_arg = Int32GetDatum(0);
worker.bgw_notify_pid = 0;
sprintf(worker.bgw_library_name, "odyssey");
sprintf(worker.bgw_function_name, "OdysseyDaemon");
snprintf(worker.bgw_name, BGW_MAXLEN, "Odyssey multi-threaded connection pooler");
RegisterBackgroundWorker(&worker);
}
void
OdysseyDaemon(Datum arg)
{
int rc;
int argc = 2;
char *argv[2];
od_instance_t odyssey;
od_instance_init(&odyssey);
argv[0] = "odyssey";
argv[1] = od_config_file;
rc = od_instance_main(&odyssey, argc, argv);
if (rc == -1) {
rc = EXIT_FAILURE;
} else {
rc = EXIT_SUCCESS;
}
od_instance_free(&odyssey);
return;
}
这是玩具式代码,示例而已,生产环境要做的工作还有很多。
6、突然不想写了
权叔亲手炮制,版权所有,如有错误实属正常,欢迎阅读,欢迎斧正。
未经允许不得链接,未经允许不得转载。