暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Linux下为PostgreSQL编译安装简单添加启动服务

数据库杂记 2023-06-27
262


前言

近期,有人问: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安装里头,直接复制一份服务文件,显得更细致。


文章转载自数据库杂记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论