
前言
近期,有人问:centos下,把PostgreSQL做成服务有相应的介绍资料吗?答案是,当然有。就在:server-start.html (PG15的第19章第3节里:Starting the Database Server: https://www.postgresql.org/docs/15/server-start.html)
这种服务创建的方法,其实与数据库本身关系并不大,基本上就是Linux系统下的基础知识。初学者可看看。
实作
前提条件:
您已经为PostgreSQL进行了源码编译安装。这里以CentOS7.9 + PostgreSQL15.3为例。
准备好一个数据库用户及其组别:
groupdel postgres
userdel postgres
-- 查下id 999, 也可以换一个
getent group | grep 999
groupadd -g 999 postgres
useradd -g 999 -u 999 postgres
passwd postgres
下载源码:
wget https://ftp.postgresql.org/pub/source/v15.3/postgresql-15.3.tar.gz
安装编译PostgreSQL所需要的依赖包:
-- root用户
yum install -y readline readline-devel flex bison openssl openssl-devel git
yum install -y gcc gcc-c++ epel-release llvm5.0 llvm5.0-devel clang libicu-devel perl-ExtUtils-Embed zlib-devel openssl openssl-devel pam-devel libxml2-devel libxslt-devel openldap-devel systemd-devel tcl-devel python-devel python3-devel lz4 lz4-devel uuid libuuid-devel
注意:这里头的systemd-devel是后边制作服务时需要的。至于里边一些tcl, python, perl之类,是可选的,不用则不需要。
配置编译项:
为了简化,配置项可以弄得尽量简单点儿。
[06:20:10-postgres@sean-rh1:/iihero/source]$ tar zxf postgresql-15.3.tar.gz
[06:20:42-postgres@sean-rh1:/iihero/source]$ cd postgresql-15.3
./configure --prefix=/usr/pgsql-15.3 --with-openssl --with-lz4 --with-libxml --with-libxslt --with-systemd -with-extra-version=" [By Sean]"
......
当然,您也可以加很多选项,基于前边的依赖包。
比如下例:
./configure LLVM_CONFIG=/usr/lib64/llvm5.0/bin/llvm-config CLANG=/opt/rh/llvm-toolset-7/root/usr/bin/clang --with-openssl --prefix=/usr/pgsql-15.3 --with-pgport=6666 --with-blocksize=8 --with-wal-blocksize=8 --with-segsize=1 --enable-profiling --enable-cassert --enable-dtrace --enable-debug --with-icu --with-uuid=e2fs --with-lz4 --with-llvm --with-python --with-libxml --with-libxslt --with-systemd -with-extra-version=" [By Sean]"
实际试验时,使用上边的简单的配置项即可,我们的主要目的是为了配置后边的服务。
在生产环境当中,其实,你可以从pg_config --configure命令直接提取已安装或编译系统中的configure选项。比如:
[21:41:06-postgres@centos2:/var/lib/pgsql]$ /usr/pgsql-14/bin/pg_config --configure
'--enable-rpath' '--prefix=/usr/pgsql-14' '--includedir=/usr/pgsql-14/include' '--mandir=/usr/pgsql-14/share/man' '--datadir=/usr/pgsql-14/share' '--libdir=/usr/pgsql-14/lib' '--with-lz4' '--with-icu' '--with-llvm' '--with-perl' '--with-python' '--with-tcl' '--with-tclconfig=/usr/lib64' '--with-openssl' '--with-pam' '--with-gssapi' '--with-includes=/usr/include' '--with-libraries=/usr/lib64' '--enable-nls' '--enable-dtrace' '--with-uuid=e2fs' '--with-libxml' '--with-libxslt' '--with-ldap' '--with-selinux' '--with-systemd' '--with-system-tzdata=/usr/share/zoneinfo' '--sysconfdir=/etc/sysconfig/pgsql' '--docdir=/usr/pgsql-14/doc' '--htmldir=/usr/pgsql-14/doc/html' 'CFLAGS=-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic' 'LDFLAGS=-Wl,--as-needed' 'LLVM_CONFIG=/usr/lib64/llvm5.0/bin/llvm-config' 'CLANG=/opt/rh/llvm-toolset-7/root/usr/bin/clang' 'PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig' 'PYTHON=/usr/bin/python3'
这样,你也可以根据实际需要进行裁减。
编译安装:
[06:30:47-postgres@sean-rh1:/iihero/source/postgresql-15.3]$ make -j4 world-bin && sudo make install-world-bin
... ...
这里采用了-j4进行并行编译。
如果想清除安装,随时可以:
sudo make distclean
进行全部清除。
编译安装完以后,所有的相关包文件都安装到目录:/usr/pgsql-15.3下边了。
至此,准备工作结束。
配置服务
因为是编译安装版,我们可以先试用一下数据库的初始化。这里postgres用户的HOME目录为:/var/lib/pgsql。我们要为它配置好环境变量:
vi .bash_profile
-- 补充下边的内容, 指定可执行路径,端口,以及PGDATA目录
export PATH=/usr/pgsql-15.3/bin:$PATH
export PGPORT=5555
export PGDATA=/var/lib/pgsql/15/pgdata
配置好后,我们可以试着执行一次初始化。
source .bash_profile
initdb -E UTF8 --locale=C -D 15/pgdata
.....
成功初始化。那么我们就可以用它来做服务的相关配置项了。
方法一:使用systemd服务管理文件
使用root用户创建一个服务文件位于:/usr/lib/systemd/system/pg153.service
-- root用户
vi /usr/lib/systemd/system/pg153.service
[Unit]
Description=PostgreSQL database server 15.3
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
User=postgres
ExecStart=/usr/pgsql-15.3/bin/postgres -D /var/lib/pgsql/15/pgdata
ExecReload=/bin/kill -HUP $MAINPID
KillMode=mixed
KillSignal=SIGINT
# TimeoutSec=infinity
# Do not set any timeout value, so that systemd will not kill postmaster
# during crash recovery.
TimeoutSec=0
# 0 is the same as infinity, but "infinity" needs systemd 229
TimeoutStartSec=0
TimeoutStopSec=1h
[Install]
WantedBy=multi-user.target
在官方文档中,用的是: TimeoutSec=infinity。这里纠正一下,使用的是后边的:三个timeout设置。
User=postgres,用于指定启动数据库的专用操作系统用户。
于是启动pg153服务,就很简单了。
systemctl start pg153
启动完以后可以得到相关状态:
[07:19:41-postgres@sean-rh1:/var/lib/pgsql/15]$ systemctl status pg153
● pg153.service - PostgreSQL database server 15.3
Loaded: loaded (/usr/lib/systemd/system/pg153.service; disabled; vendor preset: disabled)
Active: active (running) since Mon 2023-06-26 07:18:03 UTC; 26min ago
Main PID: 14527 (postgres)
Tasks: 6
Memory: 17.1M
CGroup: /system.slice/pg153.service
├─14527 /usr/pgsql-15.3/bin/postgres -D /var/lib/pgsql/15/pgdata
├─14528 postgres: checkpointer
├─14529 postgres: background writer
├─14531 postgres: walwriter
├─14532 postgres: autovacuum launcher
└─14533 postgres: logical replication launcher
当然后续你可以systemctl enable/disable来让该服务是否自启动。
方法二: 补充调整rc.local文件
因为systemd服务管理方式现在占主流,使用rc.local文件添加服务已经使用的比较少见了。
打开文件/etc/rc.local, 实际上它指向的是文件/etc/rd.d/rc.local
加上下边的一行:
su -l postgres -c '/usr/pgsql-15.3/bin/pg_ctl start -s -D /var/lib/pgsql/15/pgdata'
这样它就会变成自启动的了。 不过,要注意,这个rc.local一定要加上可执行权限,如果没有的话。
方法三:在/etc/rc.d/init.d下边创建postgresql服务启动文件
root用户:
vi /etc/rc.d/init.d/pg
su -l postgres -c '/usr/pgsql-15.3/bin/pg_ctl start -s -D /var/lib/pgsql/15/pgdata'
给它加上可执行权限:chmod +x etc/rc.d/init.d/pg
, 然后建一个服务链接:
[19:19:52-root@centos1:/etc/rc.d/rc3.d]$ ln -s ../init.d/pg S99pg
提示: rc{x}是启动级别。linux下有七个启动级别:
linux 系统启动级别分为以下七种:
rc0
: 停机(不能使用)
rc1
: 单用户模式
rc2
: 多用户模式,但是没有NFS
rc3
: 完全多用户模式
rc4
: 没有使用,系统预留
rc5
: 图形界面模式
rc6
: 重启模式(不能使用)
所以,我们这里是在rc3下边创建的那个服务启动文件。
但是呢,这个是一个相当简陋的脚本。完整的脚本应该包含start, stop等多个选项。文档里头也说了,可以从contrib/start_script/linux下抄一个,改动下即可。以下是更新版本的pg的内容:
#! /bin/sh
# chkconfig: 2345 98 02
# description: PostgreSQL RDBMS
prefix=/usr/pgsql-15.3
PGDATA="/var/lib/pgsql/15/pgdata"
PGUSER=postgres
PGLOG="$PGDATA/serverlog"
# It's often a good idea to protect the postmaster from being killed by the
# OOM killer (which will tend to preferentially kill the postmaster because
# of the way it accounts for shared memory). To do that, uncomment these
# three lines:
PG_OOM_ADJUST_FILE=/proc/self/oom_score_adj
PG_MASTER_OOM_SCORE_ADJ=-1000
PG_CHILD_OOM_SCORE_ADJ=0
# Older Linux kernels may not have /proc/self/oom_score_adj, but instead
# /proc/self/oom_adj, which works similarly except for having a different
# range of scores. For such a system, uncomment these three lines instead:
#PG_OOM_ADJUST_FILE=/proc/self/oom_adj
#PG_MASTER_OOM_SCORE_ADJ=-17
#PG_CHILD_OOM_SCORE_ADJ=0
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# What to use to start up the postmaster. (If you want the script to wait
# until the server has started, you could use "pg_ctl start" here.)
DAEMON="$prefix/bin/postmaster"
# What to use to shut down the postmaster
PGCTL="$prefix/bin/pg_ctl"
set -e
# Only start if we can find the postmaster.
test -x $DAEMON ||
{
echo "$DAEMON not found"
if [ "$1" = "stop" ]
then exit 0
else exit 5
fi
}
# If we want to tell child processes to adjust their OOM scores, set up the
# necessary environment variables. Can't just export them through the "su".
if [ -e "$PG_OOM_ADJUST_FILE" -a -n "$PG_CHILD_OOM_SCORE_ADJ" ]
then
DAEMON_ENV="PG_OOM_ADJUST_FILE=$PG_OOM_ADJUST_FILE PG_OOM_ADJUST_VALUE=$PG_CHILD_OOM_SCORE_ADJ"
fi
# Parse command line parameters.
case $1 in
start)
echo -n "Starting PostgreSQL: "
test -e "$PG_OOM_ADJUST_FILE" && echo "$PG_MASTER_OOM_SCORE_ADJ" > "$PG_OOM_ADJUST_FILE"
su - $PGUSER -c "$DAEMON_ENV $DAEMON -D '$PGDATA' >>$PGLOG 2>&1 &"
echo "ok"
;;
stop)
echo -n "Stopping PostgreSQL: "
su - $PGUSER -c "$PGCTL stop -D '$PGDATA' -s"
echo "ok"
;;
restart)
echo -n "Restarting PostgreSQL: "
su - $PGUSER -c "$PGCTL stop -D '$PGDATA' -s"
test -e "$PG_OOM_ADJUST_FILE" && echo "$PG_MASTER_OOM_SCORE_ADJ" > "$PG_OOM_ADJUST_FILE"
su - $PGUSER -c "$DAEMON_ENV $DAEMON -D '$PGDATA' >>$PGLOG 2>&1 &"
echo "ok"
;;
reload)
echo -n "Reload PostgreSQL: "
su - $PGUSER -c "$PGCTL reload -D '$PGDATA' -s"
echo "ok"
;;
status)
su - $PGUSER -c "$PGCTL status -D '$PGDATA'"
;;
*)
# Print help
echo "Usage: $0 {start|stop|restart|reload|status}" 1>&2
exit 1
;;
esac
exit 0
这样,很容易使用service pg start
来启动PostgreSQL数据库。
同时也支持service pg stop
。设成自启动,使用:chkconfig pg on
注意:
下边这一行不能去掉,去掉的话,会报错:service does not support chkconfig
# chkconfig: 2345 98 02
基于此,完整的软链接可以使用:chkconfig --add pg
小结
回过头来,我们再去看看官方文档:Starting the Database Server: https://www.postgresql.org/docs/15/server-start.html)
其实里边写的不是特别详细。
有个地方提到:
Consider carefully the timeout setting. systemd has a default timeout of 90 seconds as of this writing and will kill a process that does not report readiness within that time. But a PostgreSQL server that might have to perform crash recovery at startup could take much longer to become ready. The suggested value of
infinity
disables the timeout logic.
但是,你可以看到我在上边的例子中:
# 0 is the same as infinity, but "infinity" needs systemd 229
"infinity"的支持需要systemd的229这个版本或者更新? 而实际上我们在CentOS7.9中它的版本可能就是219。这些都是一些细节的地方,文档中并没有提的很详细。
回到头来,除了从官方文档中提取那个systemd的服务文件模板,我们也可以从yum安装里头,直接复制一份服务文件,显得更细致。





