Ban*_*jer 25 postgresql linux kill sles
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在单个查询进程/线程上不再是死刑。
有人能告诉我杀死失控的 postgres 进程的正确方法以及kill -9这些天 Postgres 的使用是多么灾难性(或良性)吗?感谢您的洞察力。
Cra*_*ger 33
voretaq7的答案涵盖了关键点,包括终止后端的正确方法,但我想添加更多解释。
kill -9(即SIGKILL)永远不应该成为您的首选默认值。当进程不响应其正常关闭请求并且 a SIGTERM( kill -15) 无效时,它应该是您的最后手段。Pg 和其他几乎所有东西都是如此。
kill -9 使被杀死的进程根本没有机会进行任何清理。
当谈到 PostgreSQL 时,Pg 看到一个被支持的被终止kill -9的支持崩溃。它知道后端可能已经损坏了共享内存——例如,因为你可以在将页面写入 shm 或修改页面的过程中中断它——所以当它注意到后端突然消失时,它会终止并重新启动所有其他后端并以非零错误代码退出。
您将在日志中看到此报告。
如果它看起来没有坏处,那是因为 Pg 在崩溃后重新启动了所有内容,并且您的应用程序正在从丢失的连接中干净地恢复。这并不是一个好主意。如果没有其他后端崩溃的测试不如 Pg 的正常功能部分那么好,并且更加复杂/多变,那么在后端崩溃处理和恢复中潜伏的错误的可能性就更高。
顺便说一句,如果你kill -9是 postmaster,然后postmaster.pid在没有确保每个postgres后端都消失的情况下删除并重新启动它,那么可能会发生非常糟糕的事情。如果您不小心杀死了 postmaster 而不是后端,看到数据库已经关闭,尝试重新启动它,在重新启动失败时删除“陈旧的”.pid 文件,并尝试再次重新启动它,这很容易发生。这是您应该避免kill -9在 Pg 周围挥手的原因之一,并且不应该删除postmaster.pid.
演示:
要准确了解kill -9后端会发生什么,请尝试以下简单步骤。打开两个终端,在每个终端和每次运行中打开 psql SELECT pg_backend_pid();。在另一个终端中的kill -9一个 PID。现在SELECT pg_backend_pid();再次在两个 psql 会话中运行。注意到他们是如何失去联系的吗?
我们杀死的会话 1:
$ 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)
Run Code Online (Sandbox Code Playgroud)
第 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)
Run Code Online (Sandbox Code Playgroud)
看看这两个会话是如何被破坏的?这就是为什么你没有kill -9后端。
vor*_*aq7 29
I found the particular process via ps aux | grep postgres and ran kill -9 pid.
不!坏的!远离后端!
说真的——不要像那样杀死 Postgres 后端——可能会发生可怕的事情(即使自 7.x 天以来已经进行了所有稳定性增强),这可能会破坏您的整个数据库,并且您的开发人员非常正确地咀嚼你这样做。
事实上,在 Postgres 内部有一种被祝福和认可的方法——它甚至在Postgres 手册中,尽管 SO 帖子在解释它方面做得更好......
SELECT pg_cancel_backend(pid)SIGINT向指定的后端
发送取消 ( ) 信号,这会取消当前正在运行的查询。
select pg_terminate_backend(pid)SIGTERM向指定的后端
发送终止 ( ) 信号,这将取消查询并中止后端(断开其连接)。
可以从pg_stat_activity表(或ps)中获取后端 ID
杀死 PostgreSQL 客户端进程应该没问题。杀死一个 PostgreSQL 守护进程可能会让你受到责骂。
由于 SQL 守护进程也有内部进程控制,因此首选方法是先尝试使用该通道。
请参阅StackOverflow 中的Stop (long) running SQL query in PostgreSQL...。
| 归档时间: |
|
| 查看次数: |
21933 次 |
| 最近记录: |