PostgreSQL KILL -9 用戶連接進程 , OMG 膽真肥

  • 2019 年 12 月 17 日
  • 筆記

在數據庫的服務器上通過linux 命令來將postgresql 殺死 例如 kill -9 xxxx,這樣做到底會對postgresql 產生什麼影響,不少人都曾經這樣干過,為什麼說這樣做,糟糕透了。

首先我們需要理解一下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 ,建議你住手。