postgres SELECT查询在我们的数据库服务器上失去控制,并开始吞噬大量内存并进行交换,直到服务器内存不足。 我通过ps aux | grep postgres
find了特定的过程 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
不再是一个死刑。
有人能够启发我,以正确的方式杀死一个失控的postgres进程,以及如何使用kill -9
与灾难(或良性)是Postgres这些天? 感谢您的洞察力。
voretaq7的答案涵盖了关键点,包括终止后端的正确方法,但我想补充一点解释。
kill -9
(即SIGKILL
)永远不会是你的首选默认值 。 如果进程没有响应正常的closures请求,并且SIGTERM
( kill -15
)没有任何作用,那么应该是最后一SIGTERM
。 Pg和其他所有事情都是如此。
kill -9
给被杀的进程没有机会做任何清理工作。
说到PostgreSQL, Pg看到一个被kill -9
终止的支持作为一个支持的崩溃 。 它知道后端可能已经损坏了共享内存,因为你可以通过将页面写入shm或修改一个页面来中断它 – 所以当它注意到后端突然消失时,它终止并重新启动所有其他后端并用一个非零的错误代码退出。
您会在日志中看到这个报告。
如果它看起来没有任何伤害,那是因为Pg在崩溃之后重启所有的东西,并且你的应用程序正在干净地从丢失的连接中恢复。 这并不是一个好主意。 如果没有其他后端崩溃比Pg正常运行的部分没有得到很好的testing,并且更复杂/多样化,所以潜伏在后端崩溃处理和恢复中的bug的可能性更高。
顺便说一句,如果你kill -9
的postmaster然后删除postmaster.pid
并重新启动,而不确保每个postgres
后端都没有了, 可能会发生非常糟糕的事情 。 如果不小心杀死了postmaster而不是后端,看到数据库已经closures,尝试重新启动它,在重新启动失败时删除了“stale”.pid文件,并试图重新启动它,这很容易发生。 这就是你应该避免在Pg周围挥动kill -9
的原因之一,而不应该删除postmaster.pid
。
示范:
要准确地看到当你kill -9
一个后端时会发生什么,试试这些简单的步骤。 打开两个terminal,分别打开psql,并在每次运行中SELECT pg_backend_pid();
。 在另一个terminal中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)
会议2,这是附带损害:
$ 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
一个后端。
I found the particular process via ps aux | grep postgres and ran kill -9 pid.
没有! 坏! 从后退离开!
认真 – 不要杀死Postgres后端 – 糟糕的事情可能会发生(甚至自7.x天以来所有的稳定性增强),可以毁掉你的整个数据库,你的开发人员是非常正确的咀嚼你出去做这个。
事实上, 在Postgres内部这样做是有福的,也是可以批准的 – 即使是在Postgres手册中,虽然这个post可以更好地解释它…
SELECT pg_cancel_backend(pid)
将取消( SIGINT
)信号发送到指定的后端,取消当前正在运行的查询。
select pg_terminate_backend(pid)
发送一个terminate( SIGTERM
)信号到指定的后端,取消查询并中止后端(删除它的连接)。
后端ID可以从pg_stat_activity
表(或ps
)
杀死一个PostgreSQL客户端进程应该没问题。 杀死一个PostgreSQL守护进程可能会让你骂。
由于SQL守护进程也有内部进程控制,所以首选的方法是先尝试使用该通道。
请参阅在 StackOverflow中停止(长时间)在PostgreSQL中运行SQL查询 。