LLVM 設置不當,開啓 JIT 導致 terminated by signal 9: Kille

前言

今天妹子發來一段信息,讓我看一下。

這個問題已經發生幾次了,都是莫名其妙的進程就會被 kill 掉。

問題研究

這個問題是她在運行一個大的存儲過程的時候,進程收到signal 9信號,異常中止了。

2021-08-09 21:19:58.695 CST [13141] LOG:  server process (PID 14107) was terminated by signal 9: Killed
2021-08-09 21:19:58.695 CST [13141] DETAIL:  Failed process was running: call yjcj_new_order_incre(1001, 202105, 3);
2021-08-09 21:19:58.695 CST [13141] LOG:  terminating any other active server processes
2021-08-09 21:19:58.695 CST [14110] yjcj@133.0.***.*****(17795)/yjcj,psql WARNING:  terminating connection because of crash of another server process
2021-08-09 21:19:58.695 CST [14110] yjcj@133.0.***.*****(17795)/yjcj,psql DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process e
xited abnormally and possibly corrupted shared memory.
2021-08-09 21:19:58.695 CST [14110] yjcj@133.0.***.*****(17795)/yjcj,psql HINT:  In a moment you should be able to reconnect to the database and repeat your command.
2021-08-09 21:19:58.695 CST [14111] yjcj@133.0.***.****(17793)/yjcj,psql WARNING:  terminating connection because of crash of another server process
2021-08-09 21:19:58.695 CST [14111] yjcj@133.0.***.****(17793)/yjcj,psql DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process e
xited abnormally and possibly corrupted shared memory.

從日誌上來看,大概在 21:19:58 出現了進程被異常 kill。經她反饋該問題已經出現好幾次了。

這個問題要直接定位有點困難,不過按照之前的經驗,一般內存要 OOM 的時候,會被操作系統進程給 kill 掉。所以我們先從操作系統日誌進行着手,看下有沒有內存 OOM kill 進程的情況。

Aug  9 21:17:35 yjcj-postgres-01 systemd-logind: Removed session 289777.
Aug  9 21:18:05 yjcj-postgres-01 systemd-logind: New session 289778 of user postgres.
Aug  9 21:18:05 yjcj-postgres-01 systemd: Started Session 289778 of user postgres.
Aug  9 21:18:05 yjcj-postgres-01 systemd-logind: Removed session 289778.
Aug  9 21:18:35 yjcj-postgres-01 systemd-logind: New session 289779 of user postgres.
Aug  9 21:18:35 yjcj-postgres-01 systemd: Started Session 289779 of user postgres.
Aug  9 21:18:35 yjcj-postgres-01 systemd-logind: Removed session 289779.
Aug  9 21:19:05 yjcj-postgres-01 systemd-logind: New session 289780 of user postgres.
Aug  9 21:19:05 yjcj-postgres-01 systemd: Started Session 289780 of user postgres.
Aug  9 21:19:05 yjcj-postgres-01 systemd-logind: Removed session 289780.
Aug  9 21:19:35 yjcj-postgres-01 systemd-logind: New session 289781 of user postgres.
Aug  9 21:19:35 yjcj-postgres-01 systemd: Started Session 289781 of user postgres.

從操作系統的日誌上來看,並沒有出現主機 OOM kill 進程的情況。

關於 OOM 這裏稍微說一下。每當系統內存不足並且找不到可用內存空間時,就會調用 out_of_memory 函數,並使用 select_bad_process() 函數。這個函數將從 badness() 函數中獲得分數。最垃圾的進程是將被 kill。badness() 函數遵循一些規則來選擇進程。

在進行清單檢查之後,OOM 爲每個進程設置 “oom_score”(分數),然後將該值與內存使用量相乘。具有較大值的進程將很有可能被 OOM killer 給終止。

扯的有點多,既然不是 OOM killer 搞的鬼,那應該是別的什麼原因。對上述信息進行了相關的搜索,發現社區中有類似案例。

這個問題需要使用 gdb 進行調試。通過調試發現導致出現問題的是 llvm,也就是 JIT 這個功能。但是遺憾的是我這裏找不到具體的 SQL 語句。我這邊情況是存儲過程,不太好調試。(這個存儲過程裏面的內容特別多)。

我們當前是雲計算的環境,操作系統是 centos 7.4,這臺主機的 LLVM 軟件包沒有安裝。PostgreSQL 軟件包是直接克隆好之後下發的。所以這裏出現此類問題是有極大可能的。

postgres=# set jit to on;
SET
postgres=# set jit_above_cost to 1;
SET
postgres=# explain select count(*) from pg_class;
                                   QUERY PLAN                                    
---------------------------------------------------------------------------------
 Aggregate  (cost=42.30..42.31 rows=width=8)
   ->  Seq Scan on pg_class  (cost=0.00..39.64 rows=1064 width=0)
 JIT:
   Functions: 2
   Options: Inlining false, Optimization false, Expressions true, Deforming true
(5 rows)

數據庫可以打開 JIT 的,但是實際上操作系統根本就沒有 llvm。

[root@yjcj-telepg-01 /]# llvm-config --version
-bash: llvm-config: command not found

find . -name "llvm-config" -print

同時查看了一下相關的帖子,發現stackexchange上有個案例和我們這也有點類似。

最終也是通過 disable jit 解決了這類問題。於是我們嘗試把 jit 設置成了 off,真就解決了這個問題。

後記

針對我的這個 case,是操作系統上的 LLVM 安裝設置不正確導致進程異常 terminating。後面我會把 LLVM 安裝一下再次打開這個功能在進行驗證。

參考鏈接:

https://www.postgresql.org/message-id/flat/CA%2BHiwqFhfxXHk5gazr77kKO3QAp8GO-_dq33n7Oazw2iHTS3tQ%40mail.gmail.com

https://dba.stackexchange.com/questions/259926/queries-on-large-database-kill-connection-to-the-server-works-with-limit

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/G_XBUuUq3Z_3xAxEndZ3BA