voretaq7的答案涵盖了关键点,包括终止后端的正确方法,但我想补充一点解释。
kill -9
(即SIGKILL
)永远不要成为您的首选。当进程不响应其正常的关闭请求并且SIGTERM
(kill -15
)没有任何作用时,这应该是您的最后选择。Pg和几乎所有其他内容都是如此。
kill -9
使被杀死的进程根本没有机会进行任何清理。
当涉及到PostgreSQL时,Pg会看到一个kill -9
以崩溃终止的后端。它知道后端可能损坏了共享内存-例如,您可能会通过将页面写入shm或修改一个页面来中途中断它-因此当它注意到某个后端突然消失时,它将终止并重新启动所有其他后端并以非零错误代码退出。
您会在日志中看到此报告。
如果它看起来没有害处,那是因为Pg在崩溃后正在重新启动所有操作,并且您的应用程序正在从丢失的连接中完全恢复。那并不是一个好主意。如果没有其他事情比Pg的正常运行部分更好地测试了后端崩溃,并且更加复杂/多变,那么隐藏在后端崩溃处理和恢复中的错误的可能性就会更高。
顺便说一句,如果您kill -9
的邮件管理员postmaster.pid
在没有确保每个postgres
后端都消失的情况下删除并重新启动,则可能会发生非常糟糕的事情。如果您不小心杀死了邮局管理员而不是后端,看到数据库崩溃了,尝试重新启动它,并在重新启动失败时删除了“陈旧” .pid文件,然后尝试重新启动它,则很容易发生这种情况。这就是您应该避免kill -9
在Pg周围挥手而不应该删除的原因之一postmaster.pid
。
演示:
要确切了解kill -9
后端时会发生什么,请尝试以下简单步骤。打开两个终端,分别在每个run中运行psql SELECT pg_backend_pid();
。在另一个终端中,kill -9
其中一个PID。现在SELECT pg_backend_pid();
再次在两个psql会话中运行。注意到他们俩都失去了联系吗?
第一场,我们杀死了:
$ psql regress
psql (9.1.4)
Type "help" for help.
regress=# select pg_backend_pid();
pg_backend_pid
----------------
6357
(1 row)
[kill -9 of session one happens at this point]
regress=# select pg_backend_pid();
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
pg_backend_pid
----------------
6463
(1 row)
第二部分,附带损害:
$ psql regress
psql (9.1.4)
Type "help" for help.
regress=# select pg_backend_pid();
pg_backend_pid
----------------
6283
(1 row)
[kill -9 of session one happens at this point]
regress=# select pg_backend_pid();
WARNING: terminating connection because of crash of another server process
DETAIL: The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT: In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
pg_backend_pid
----------------
6464
(1 row)
看看两个会议如何中断?这就是为什么您没有kill -9
后端。