Linux,  PostgreSQL

如何手工启停PostgreSQL数据库

零说明

对于一个数据库而言,正常情况下,安装和部署之后,正常对外提供服务就好。很少有人去启停数据库,但是,数据库偶尔也有需要被管理维护的时候,这时候就得正确启停数据库了。另外,作为一名数据库初学者,新上手的DBA,我们不得不学会如何正确的手工启停跑在Linux服务器上的PostgreSQL数据库,毕竟这是最最基本的对于数据库的操作。

前一篇文章中,我们已经在Linux服务器上通过编译源代码的方式,安装部署了一套PostgreSQL 13.2版本的的数据库。接下来,直奔主题,我们来看如何正确手工启停数据库?

一 查看数据库是否正常运行?

PostgreSQL数据库想要对外提供正常服务,其前提条件是数据库必须正常启动运行。我们可以通过查看数据库的后台进程是否存在来做判断。

[postgres@iZbp1anc2b2vggfj0i0oovZ ~]$ ps -ef|grep postgres
root     21898 21877  0 Mar29 pts/0    00:00:00 su - postgres
postgres 21899 21898  0 Mar29 pts/0    00:00:00 -bash
postgres 21928     1  0 Mar29 ?        00:00:00 /data/postgres/13.2/bin/postgres
postgres 21930 21928  0 Mar29 ?        00:00:00 postgres: checkpointer 
postgres 21931 21928  0 Mar29 ?        00:00:00 postgres: background writer 
postgres 21932 21928  0 Mar29 ?        00:00:00 postgres: walwriter 
postgres 21933 21928  0 Mar29 ?        00:00:00 postgres: autovacuum launcher 
postgres 21934 21928  0 Mar29 ?        00:00:01 postgres: stats collector 
postgres 21935 21928  0 Mar29 ?        00:00:00 postgres: logical replication launcher 
postgres 26820 21899  0 17:07 pts/0    00:00:00 ps -ef
postgres 26821 21899  0 17:07 pts/0    00:00:00 grep --color=auto postgres
[postgres@iZbp1anc2b2vggfj0i0oovZ ~]$ 

从上,可以看到数据库的后台进程是存在的,核心进程postgres的进程号是21928,同时,检查点进程checkpointer同比Oracle的CKPT进程,数据库写进程,主要负责将shared buffer中的脏数据写回到磁盘上,类比Oracle的DBWR进程,以及日志写进程walwriter,类比Oracle的LGWR,以及垃圾回收进程autovacuum,统计信息收集进程stats collector,逻辑复制进程,logical replication launcher进程。且,这些后台进程的父进程号都是postgres后台进程的进程号,21928。说明,这些进程都是postgres的子进程,由它fork出来的。

[postgres@iZbp1anc2b2vggfj0i0oovZ ~]$ pstree -pl 21928
postgres(21928)─┬─postgres(21930)
                ├─postgres(21931)
                ├─postgres(21932)
                ├─postgres(21933)
                ├─postgres(21934)
                └─postgres(21935)
[postgres@iZbp1anc2b2vggfj0i0oovZ ~]$

也可以以postgres用户,通过这个命令来检查数据库服务状态:

[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ pg_ctl status
pg_ctl: server is running (PID: 21928)
/data/postgres/13.2/bin/postgres
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ 

因此,可以初步判断数据库是正常的。当然,最严谨的判断,还是得找一个客户端程序,或者应用系统来测试一下,是否可以正常连接访问数据库?能否进行正常的读写操作?比如通过psql工具,是否能连接并操作这个数据库?这里就不再扩展了。

二如何手工启动PostgreSQL数据库

想要正确启动Linux服务器上的PostgreSQL数据库,我们依赖于pg_ctl命令,和PGDATA这个环境变量。前者位于PostgreSQL软件安装路径下的bin路径下,后者则表示一个数据库集群cluster的根路径,注意这里的cluster是一个逻辑上的概念,跟Oracle数据库的cluster完全是两码事,完全不挨着。关于PostgreSQL cluster的内容,在后续的课程中,我会详细讲述。当然,参照上一篇文章中,如何在Linux上编译源码安装PostgreSQL数据库,我们已经设置和配置好了PATH和PGDA这两个环境变量。

[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ which pg_ctl 
/data/postgres/13.2/bin/pg_ctl
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ pg_ctl start -l /home/postgres/startup.log 
waiting for server to start.... done
server started
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ pg_ctl status
pg_ctl: server is running (PID: 16386)
/data/postgres/13.2/bin/postgres
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ ps -ef|grep postgres
root      6273 15860  0 11:19 pts/0    00:00:00 su - postgres
postgres  6274  6273  0 11:19 pts/0    00:00:00 -bash
postgres 16386     1  0 11:27 ?        00:00:00 /data/postgres/13.2/bin/postgres
postgres 16388 16386  0 11:27 ?        00:00:00 postgres: checkpointer 
postgres 16389 16386  0 11:27 ?        00:00:00 postgres: background writer 
postgres 16390 16386  0 11:27 ?        00:00:00 postgres: walwriter 
postgres 16391 16386  0 11:27 ?        00:00:00 postgres: autovacuum launcher 
postgres 16392 16386  0 11:27 ?        00:00:00 postgres: stats collector 
postgres 16393 16386  0 11:27 ?        00:00:00 postgres: logical replication launcher 
postgres 16401  6274  0 11:30 pts/0    00:00:00 ps -ef
postgres 16402  6274  0 11:30 pts/0    00:00:00 grep --color=auto postgres
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ psql
psql (13.2)
Type "help" for help.
​
postgres=# 

完整的启动PostgreSQL数据库的命令是:

[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ pg_ctl start -D /data/postgres/13.2/data/ -l /home/postgres/startup.log 

命令行参数中的start选项,表示要启动数据库。该选项是必需项。

-D 选项,是指指出数据库集群的根路径。由于,我们之前已经配置了PGDATA环境变量,所以,我们可以在命令行上省略该选项。如果,没有正确配置指定PGDATA环境变量,则要显示指出。

-l选项,表示数据库启动日志写入到哪个文件中。非必需项。

查看一下日志文件内容:

[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ cat /home/postgres/startup.log 
2021-03-26 11:27:59.814 CST [16386] LOG:  starting PostgreSQL 13.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20190507 (Red Hat 8.3.1-4), 64-bit
2021-03-26 11:27:59.814 CST [16386] LOG:  listening on IPv6 address "::1", port 5432
2021-03-26 11:27:59.815 CST [16386] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2021-03-26 11:27:59.816 CST [16386] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-03-26 11:27:59.819 CST [16387] LOG:  database system was shut down at 2021-03-26 11:26:13 CST
2021-03-26 11:27:59.821 CST [16386] LOG:  database system is ready to accept connections
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ 

三如何手工关闭PostgreSQL数据库

同样,我们通过pg_ctl工具来干净正确的关闭数据库。

[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ pg_ctl stop -m fast
waiting for server to shut down.... done
server stopped
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ cat /home/postgres/startup.log 
2021-03-26 11:27:59.814 CST [16386] LOG:  starting PostgreSQL 13.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20190507 (Red Hat 8.3.1-4), 64-bit
2021-03-26 11:27:59.814 CST [16386] LOG:  listening on IPv6 address "::1", port 5432
2021-03-26 11:27:59.815 CST [16386] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2021-03-26 11:27:59.816 CST [16386] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-03-26 11:27:59.819 CST [16387] LOG:  database system was shut down at 2021-03-26 11:26:13 CST
2021-03-26 11:27:59.821 CST [16386] LOG:  database system is ready to accept connections
2021-03-26 11:39:35.140 CST [16386] LOG:  received fast shutdown request
2021-03-26 11:39:35.141 CST [16386] LOG:  aborting any active transactions
2021-03-26 11:39:35.142 CST [16386] LOG:  background worker "logical replication launcher" (PID 16393) exited with exit code 1
2021-03-26 11:39:35.142 CST [16388] LOG:  shutting down
2021-03-26 11:39:35.152 CST [16386] LOG:  database system is shut down
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ ps -ef|grep postgres
root      6273 15860  0 11:19 pts/0    00:00:00 su - postgres
postgres  6274  6273  0 11:19 pts/0    00:00:00 -bash
postgres 16452  6274  0 11:40 pts/0    00:00:00 ps -ef
postgres 16453  6274  0 11:40 pts/0    00:00:00 grep --color=auto postgres
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ 

命令行选项stop,表示要关闭数据库。必需项。

-m fast,表示以fast这个模式mode,快速干净的关闭数据库。关闭过程中会回滚相关未提交事务,下次启动数据库时,无需instance recovery,类似于Oracle的shutdown immediate方式关闭数据库。非必需项。

四 关于pg_ctl的更多使用选项

pg_ctl的命令很好记也很容易上手,ctl表示control的意思。类比Oracle数据库中相关的命令行工具:lsnrctl,srvctl,crsctl。

命令行上执行,pg_ctl –help可以查看到更完整的帮助信息和相关命令行选项和参数。

[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ pg_ctl --help
pg_ctl is a utility to initialize, start, stop, or control a PostgreSQL server.
​
Usage:
  pg_ctl init[db]   [-D DATADIR] [-s] [-o OPTIONS]
  pg_ctl start      [-D DATADIR] [-l FILENAME] [-W] [-t SECS] [-s]
                    [-o OPTIONS] [-p PATH] [-c]
  pg_ctl stop       [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]
  pg_ctl restart    [-D DATADIR] [-m SHUTDOWN-MODE] [-W] [-t SECS] [-s]
                    [-o OPTIONS] [-c]
  pg_ctl reload     [-D DATADIR] [-s]
  pg_ctl status     [-D DATADIR]
  pg_ctl promote    [-D DATADIR] [-W] [-t SECS] [-s]
  pg_ctl logrotate  [-D DATADIR] [-s]
  pg_ctl kill       SIGNALNAME PID
​
Common options:
  -D, --pgdata=DATADIR   location of the database storage area
  -s, --silent           only print errors, no informational messages
  -t, --timeout=SECS     seconds to wait when using -w option
  -V, --version          output version information, then exit
  -w, --wait             wait until operation completes (default)
  -W, --no-wait          do not wait until operation completes
  -?, --help             show this help, then exit
If the -D option is omitted, the environment variable PGDATA is used.
​
Options for start or restart:
  -c, --core-files       allow postgres to produce core files
  -l, --log=FILENAME     write (or append) server log to FILENAME
  -o, --options=OPTIONS  command line options to pass to postgres
                         (PostgreSQL server executable) or initdb
  -p PATH-TO-POSTGRES    normally not necessary
​
Options for stop or restart:
  -m, --mode=MODE        MODE can be "smart", "fast", or "immediate"
​
Shutdown modes are:
  smart       quit after all clients have disconnected
  fast        quit directly, with proper shutdown (default)
  immediate   quit without complete shutdown; will lead to recovery on restart
​
Allowed signal names for kill:
  ABRT HUP INT KILL QUIT TERM USR1 USR2
​
Report bugs to <pgsql-bugs@lists.postgresql.org>.
PostgreSQL home page: <https://www.postgresql.org/>
[postgres@iZbp1anc2b2vggfj0i0oovZ postgresql-13.2]$ 

需要说明的是:

  • pg_ctl命令行工具囊括了start/stop/restart/reload/status/promote/logrotate/init等诸多日常维护操作的选项,需要用到的命令,我们届时遇到时再做说明,这里暂时不一一说明。
  • 另外,在restart/stop选项中,其支持使用的选项smart等价于Oracle的shutdown normal,fast等价于Oracle的shutdown immediate,immediate等价于Oracle的shutdown abort。因此,我们在PostgreSQL数据库中要谨慎使用immediate选项来重启、关闭数据库。
  • 本文档描述的是针对源码安装的PostgreSQL数据库,如果是通过RPM软件包安装的数据库软件,或者其它平台如,Ubuntu,Mac OS、Solaris则不适用。