杀死-9 postgres进程


25

Postgres SELECT查询在我们的数据库服务器上失控,开始吞噬大量内存并进行交换,直到服务器内存耗尽。我通过ps aux | grep postgres和运行找到了特定的过程kill -9 pid。这终止了进程,并且内存按预期方式释放。系统的其余部分和postgres查询似乎不受影响。该服务器在SLES 9 SP4上运行postgres 9.1.3。

但是,我们的一位开发人员因用杀死了postgres流程而对我表示敬意kill -9,并说它将取消整个postgres服务。实际上,事实并非如此。我已经做过几次了,还没有看到任何负面影响。

话虽如此,但在进一步阅读后,看起来kill pid没有标志是杀死失控的postgres进程的首选方法,但是对于postgres社区中的其他用户,这听起来也像是postgres多年来“变得更好”,因此kill -9在单个查询进程/线程上不再是死刑判决。

有人可以启发我采取适当的方法来杀死失控的kill -9Postgres 流程,以及最近几天使用Postgres 带来的灾难性(或良性)后果吗?感谢您的见解。

Answers:


31

voretaq7答案涵盖了关键点,包括终止后端正确方法,但我想补充一点解释。

kill -9(即SIGKILL)永远不要成为您的首选。当进程不响应其正常的关闭请求并且SIGTERMkill -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后端。


1
这里所有非常好的答案,我可能会非常谦虚。我可以将它们全部标记为已接受,但是@Craig Ringer在这里有一些额外的要点,确实使它产生了变化。再次感谢SF为我清除了我的坏习惯!
Banjer 2012年

2
@克雷格:真是太好了;并进行示范,希望我能对此100倍投票。我是一名软件开发人员,从6.x天开始每天都与PG一起工作,您的响应已来临!真好!
基洛

2
好答案。附录:如果您有一个绝对不会死的后端进程-不使用pg_terminate_backend,不使用服务器堆栈重新启动,不使用任何东西,则可以根据需要将其杀死,但要确保数据库具有有效的备份。您可以通过以下两种方法来做到这一点:您可以使用pg_basebackup或类似方法(或just rsyncpg_start\stop_backup)来备份数据目录(在继续之前测试备份!),或者可以用于pg_dump[all]挽救数据。只有这样,您才应该考虑kill -9,或重新启动等。
Zac B

1
@ZacB是的,如果杀死了它,请确保所有后端都消失了。最重要的是,永远不要删除postmaster.pid。曾经
Craig Ringer 2012年

29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
没有!坏!远离后端!

认真地-不要杀死这样的Postgres后端-可能发生可怕的事情(即使是自7.x天以来所做的所有稳定性增强)都可能浪费您的整个数据库,而您的开发人员则无可厚非你出去做这个。

实际上,在Postgres中一种受祝福和认可的方法来执行此操作 -即使在Postgres手册中,尽管SO post可以更好地解释它。

SELECT pg_cancel_backend(pid)
SIGINT向指定的后端 发送cancel()信号,该信号将取消当前正在运行的查询。

select pg_terminate_backend(pid)
SIGTERM向指定的后端 发送终止()信号,该信号将取消查询并中止后端(删除其连接)。

可以从pg_stat_activity表(或ps)中获取后端ID


4
万一有人对这可怕的事情感到疑惑,这kill -9与在被杀死的进程方面突然关闭系统电源并没有什么不同:Pg非常容忍后端崩溃(例如kill -9),并且永远不会有数据损坏。这里是贪污,如果你杀了邮政局长,删除postmaster.pid,并重新启动也没有第一次杀人每一个后端。这破坏您的数据库,但要花费更多kill -9的钱而不只是后端。kill -9邮递员没有时间杀死后端,这就是为什么这样做很危险。
Craig Ringer

2
就像我上周遇到的紧急咨询案一样。严重损坏了他们的数据库,由于备份失败(并且他们没有自动测试其还原)而损失了两天的工作,因此关闭了48小时。不要删除postmaster.pid
Craig Ringer 2014年

8

终止PostgreSQL客户端进程应该没问题。终止PostgreSQL守护进程可能会使您受骂。

由于SQL守护程序也具有内部过程控制,因此首选方法是首先尝试使用该通道。

请参阅StackOverflow中的停止(长时间)在PostgreSQL中运行SQL查询...。


4
kill -9无论如何都不应该是您的默认选择,这是不得已的选择。发送“ SIGTERMwith” kill -TERM或“ plain”,kill并且如果接收方过一会儿仍未答复,则仅应考虑kill -KILLkill -9)。
Craig Ringer 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.