PostgreSQL KILL -9 用戶連接進程 , OMG 膽真肥
- 2019 年 12 月 17 日
- 筆記
首先我們需要理解一下postgresql 在 linux中的運行機制,system call and fork() system call ,其中
是system call
postgres 102414 1 0 08:34 ? 00:00:00 /usr/local/postgres/bin/postgres -D /pgdata/data
在下邊的這些就為 fork() sytem call
postgres 102415 102414 0 08:34 ? 00:00:00 postgres: logger
postgres 102417 102414 0 08:34 ? 00:00:00 postgres: checkpointer
postgres 102418 102414 0 08:34 ? 00:00:00 postgres: background writer
postgres 102419 102414 0 08:34 ? 00:00:00 postgres: walwriter
postgres 102420 102414 0 08:34 ? 00:00:00 postgres: autovacuum launcher
postgres 102421 102414 0 08:34 ? 00:00:00 postgres: archiver
postgres 102422 102414 0 08:34 ? 00:00:01 postgres: stats collector
postgres 102423 102414 0 08:34 ? 00:00:00 postgres: logical replication launcher
postgres 102415 102414 0 08:34 ? 00:00:00 postgres: logger
postgres 102417 102414 0 08:34 ? 00:00:00 postgres: checkpointer
postgres 102418 102414 0 08:34 ? 00:00:00 postgres: background writer
postgres 102419 102414 0 08:34 ? 00:00:00 postgres: walwriter
postgres 102420 102414 0 08:34 ? 00:00:00 postgres: autovacuum launcher
postgres 102421 102414 0 08:34 ? 00:00:00 postgres: archiver
postgres 102422 102414 0 08:34 ? 00:00:01 postgres: stats collector
postgres 102423 102414 0 08:34 ? 00:00:00 postgres: logical replication launcher
上面的通過調用fork()來創建一個新進程。此系統調用複製當前進程,在進程表中創建一個具有許多與當前進程相同屬性的新條目。新創建的進程將是調用進程的子進程
所以父進程為pid 字進程為ppid

當然也可以通過 pstree 來查看當前主線程之間的從屬關係

PostgreSQL 調用LINUX 操作系統的信號種類有以下幾種
1 Abrt 異常終止信號
2 int 外部中斷,類似於Ctrl +C 的結果
3 quit 直接清理正在運行的線程,並且對臨時產生的文件不清理
4 term 這個命令就是就是我們熟悉的 kill 命令
5 hup 重新初始化線程的命令
6 用戶調用定義
下面我們做一個test , 看看我們要是kill -9 一個用戶連接會有什麼問題

下面是在kill 當前連接到數據庫的用戶process 後的日誌

如果圖看不清我把關鍵的一句粘一下
WARNING: terminating connection because of crash of another server process
我們在對比一下kill 用戶連接的進程後的,database 的那些子進程的數字,倒吸一口涼氣了吧。

那馬上看到這裡有人就會產生一個問題,那我怎麼kill掉 那個 白佔著資源,不幹活的用戶。
(問題答案將在文末給出)
那麼我們翻過來的看一下,在kill -9 一個用戶連接的process後會發生什麼
1 用戶的連接process 被kill -9 幹掉2
2 終止任何其他活躍的服務器進程
3 警告因為你的這項操作會導致服務器postgresql其他的進程crash
4 所有的服務器的postgresql processes 重新初始化
也就是日誌的這幾句話
database system was not properly shut down; automatic recovery in progress
redo starts at 5/1C000098
invalid record length at 5/1C000108: wanted 24, got 0
redo done at 5/1C0000D0
database system is ready to accept connections
OK 到這裡你還敢隨便 kill -9 人家用戶的連接,尤其是幾百G 或上T 的大庫,Are you crazy ?
那到底正確的做法是什麼
pg_terminate_backend 命令在數據庫裏面去KILL 掉這個用戶的連接。

而且不會對數據庫產生任何的危害。(見上圖)
所以你還在天天的kill -9 用戶的process ,建議你住手。