有几种关闭数据库服务器的方法。在后台,它们都简化为向主管 postgres
进程发送信号。
如果您使用的是 PostgreSQL 的预打包版本,并且您使用其规定来启动服务器,那么您还应该使用其规定来停止服务器。 有关详细信息,请参阅包级文档。
直接管理服务器时,可以通过向 postgres
进程发送不同的信号来控制关闭的类型:
这是智能关闭模式。在接收SIGTERM后, 服务器将不允许新连接,但是会让现有的会话正常结束它们的工作。仅当所有的会话终止后它才关闭。 如果服务器处在线备份模式,它将等待直到在线备份模式不再被激活。当在线备份模式被激活时, 仍然允许新的连接,但是只能是超级用户的连接(这一例外允许超级用户连接来终止在线备份模式)。 如果服务器在恢复时请求智能关闭,恢复和流复制只有在所有正常会话都终止后才停止。
这是快速关闭模式。服务器不再允许新的连接,并向所有现有服务器进程发送SIGTERM,让它们中断当前事务并立刻退出。然后服务器等待所有服务器进程退出并最终关闭。 如果服务处于在线备份模式,备份模式将被终止并致使备份无用。
这是立即关闭模式。服务器将给所有子进程发送 SIGQUIT并且等待它们终止。如果有任何进程没有在 5 秒内终止,它们将被发送 SIGKILL。主服务器进程将在所有子进程退出之后立刻退出,而无需做普通的数据库关闭处理。这将导致在下一次启动时(通过重放 WAL 日志)恢复。只在紧急 时才推荐这种方式。
pg_ctl程序提供了一个发送这些信号关闭服务器的方便的接口。 另外,你在非 Windows 系统上可以用kill
直接发送这些信号。可以用ps
程序或者从数据目录的postmaster.pid
文件中找到postgres
进程的PID。例如,要做一次快速关闭:
$ kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`
最好不要使用SIGKILL关闭服务器。这样做将会阻止服务器释放共享内存和信号量。
此外,使用SIGKILL杀掉postgres
进程时,postgres
不会有机会将信号传播到它的子进程,所以可能也必须手工杀掉单个的子进程。
要终止单个会话同时允许其他会话继续,使用pg_terminate_backend()
(参阅表 9.84) 或发送SIGTERM信号到该会话相关的子进程。