在Ubuntu下用apt安装postgresql后,一般会生成两个systemctl服务(通常位于/lib/system/systemd),一个是postgresql.service,另一个是带参数的postgresql@.service,其中参数是Postgresql的大版本号。后者可以通过systemctl start postgresql@18-main.service启动,其中18是版本号,可以换成其他安装的版本。
笔者遇到的问题是,笔者将Postgresql版本从16升级到了18(用的同样的配置同样的端口号),但想保留16一段时间以防万一。于是在升级时简单用systemctl stop postgresql@16-main.service,systemctl stop postgresql@18-main.service简单地切换了下。但笔者的机器断电了一次,重启后一些依赖数据库的其他服务都挂了。于是进行了研究,发现开机自动重启的是16版本。
经过仔细研究,笔者发现
- Ubuntu安装Postgresql后,注册的开机启动服务其实是
postgresql.service,并不是具体指向版本的postgresql@16-main.service或者postgresql@18-main.service;- 查看开机启动状态
systemctl is-enabled postgresql.service返回enabled,systemctl is-enabled postgresql@16-main.service和systemctl is-enabled postgresql@18-main.service返回enabled-runtime - 这篇翻译官方文档的博客给出
enabled-runtime是“已经通过 /run/systemd/system/ 目录下的 Alias= 别名、 .wants/ 或 .requires/ 软连接被临时启用”; - 实际可以发现
postgresql@16-main.service和postgresql@18-main.service均存在于/run/systemd/generator/postgresql.service.wants;
- 查看开机启动状态
- 直接运行
systemctl stop postgresql.service会尝试启动所有存在的Postgresql版本;并在/run/systemd/generator/postgresql.service.wants创建对应所有版本的postgresql@<版本号>-main.service。- 这样因为端口冲突,16启动后18就启动失败了。
于是问题转化为如何让postgresql.service只启动18而不启动16。上网搜索和询问AI均建议删除原postgresql.service并将postgresql@18-main.service直接软连接到postgresql.service上面,但这显然违背了官方的服务管理的框架。
于是笔者在/lib/systemd下查找了下所有postgres开头的文件,果然有所发现,在/lib/systemd/system-generators下还有一个postgresql-generator文件,打开后内容如下
1 |
|
可见在/run/systemd/generator/postgresql.service.wants生成启动服务是根据Postgresql配置文件里面的start.conf决定的。于是官方的解决方法应该是把16版本配置文件目录/etc/postgresql/16/main里面的start.conf里面的内容从auto改为manual(注释中有给出内容的选项和含义)。