2022年3月9日 星期三

PostgreSQL Session 效能監控 - sar 與 pidstat

最近時常會遇到一些資料庫效能上的瓶頸,想要監控資料庫主機的硬體資源使用狀況、以及特定連線所消耗的資源,就找到了這兩個方便的指令,sar 與 pidstat 皆是在 Linux 的系統工具 sysstat 裡面有提供。

如果找不到指令直接安裝 sysstat 即可以使用。
yum install -y sysstat 


sar

sar 指令可以用來監控主機的 CPU記憶體I/O網路等狀態,透過紀錄這些資訊可以幫助我們找出主機可能存在的效能瓶頸。

使用方法:
sar [選項] [計錄時間間隔(秒)] [錄次數]

顯示選項
-A              全部資訊
-u [ALL]    CPU使用狀況(預設顯示此項目)
-r               記憶體使用狀況
-q             loadavg
-b             顯示I/O
-n DEV      網路  

寫 Log 檔案記錄
-o sar.file    紀錄檔案
-f  sar.file    讀取檔案

使用上有幾種排列組合可選:
1.  sar + 選項 
顯示系統本身有記錄的近期狀況,間隔為每10分鐘一筆,沒帶選項預設為顯示 CPU。
[root@localhost ~]# sar
Linux 3.10.0-1160.el7.x86_64 (localhost.localdomain)    03/09/2022      _x86_64_        (4 CPU)

11:00:42 AM       LINUX RESTART

11:10:01 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle
11:20:01 AM     all      0.13      0.00      0.16      0.01      0.00     99.69
11:30:01 AM     all      0.13      0.00      0.15      0.01      0.00     99.72
11:40:01 AM     all      0.13      0.00      0.15      0.02      0.00     99.70
11:50:01 AM     all      0.12      0.00      0.15      0.02      0.00     99.70
12:00:01 PM     all      0.09      0.00      0.14      0.02      0.00     99.76
12:10:01 PM     all      0.86      0.00      0.89      0.36      0.00     97.90
12:20:01 PM     all      0.15      0.00      0.26      0.02      0.00     99.57
12:30:01 PM     all      0.18      0.00      0.28      0.00      0.00     99.54
Average:        all      0.22      0.00      0.27      0.06      0.00     99.45

01:36:01 PM       LINUX RESTART

01:40:01 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
01:50:01 PM     all      0.08      0.00      0.16      0.00      0.00     99.76
02:00:01 PM     all      0.08      0.00      0.16      0.00      0.00     99.75
02:10:01 PM     all      0.09      0.00      0.17      0.02      0.00     99.72
Average:        all      0.08      0.00      0.16      0.01      0.00     99.75
[root@localhost ~]#



2.  sar + 選項 + 時間間隔
指定監控項目並選擇,每隔多久顯示一次,以下範例為每 5 秒顯示一次,直到 Ctrl +C 停止時會顯示最後以及平均狀況。
[root@localhost ~]# sar -u 5
Linux 3.10.0-1160.el7.x86_64 (localhost.localdomain)    03/09/2022      _x86_64_        (4 CPU)

02:13:17 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
02:13:22 PM     all      0.05      0.00      0.10      0.00      0.00     99.85
02:13:27 PM     all      0.00      0.00      0.10      0.00      0.00     99.90
^C #手動中止

02:13:29 PM     all      0.09      0.00      0.09      0.00      0.00     99.82
Average:        all      0.04      0.00      0.10      0.00      0.00     99.86

3.  sar + 選項 + 時間間隔 + 次數
指定監控項目、時間間隔、蒐集的總次數。
[root@localhost ~]# sar -u 5 2
Linux 3.10.0-1160.el7.x86_64 (localhost.localdomain)    03/09/2022      _x86_64_        (4 CPU)

02:15:45 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
02:15:50 PM     all      0.05      0.00      0.20      0.00      0.00     99.75
02:15:55 PM     all      0.05      0.00      0.15      0.00      0.00     99.80
Average:        all      0.05      0.00      0.18      0.00      0.00     99.77

如果有需要寫 Log 檔案的話,可以透過 > 導向的方式落檔案記錄,另外也可以選擇 sar 提供的寫檔案選項,此方法會記錄成為一個 Binary 檔案,無法直接編輯檢視,但可以透過 sar 指令讀取檢視,使用上提供很高的彈性。

下面的指令 -A 蒐集所有資訊,-o sar.file 將檔案記錄到 sar.file 這個檔案,每隔一秒蒐集一次總共記錄五次。
sar -A -o sar.file 1 5

記錄完成後可以透過下面指令讀取檔案,透過選擇不同的選項,可以檢視不同的資訊。
sar -u -f  sar.file
sar -b -f  sar.file

呈現結果如下,雖然檔案為 Binary 檔案無法直接讀取,但可以很方便地蒐集大量資訊並且有效地透過指令檢視後再篩選需要的內容出來。
[root@localhost ~]# sar -u -f  sar.file 1 5
Linux 3.10.0-1160.el7.x86_64 (localhost.localdomain)    03/09/2022      _x86_64_        (4 CPU)

03:39:11 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
03:39:12 PM     all      0.00      0.00      0.25      0.25      0.00     99.51
03:39:13 PM     all      0.00      0.00      0.25      0.00      0.00     99.75
03:39:14 PM     all      0.25      0.00      0.00      0.00      0.00     99.75
03:39:15 PM     all      0.00      0.00      0.00      0.00      0.00    100.00
03:39:16 PM     all      0.00      0.00      0.25      0.00      0.00     99.75
Average:        all      0.05      0.00      0.15      0.05      0.00     99.75
[root@localhost ~]# sar -b -f  sar.file 1 5
Linux 3.10.0-1160.el7.x86_64 (localhost.localdomain)    03/09/2022      _x86_64_        (4 CPU)

03:39:11 PM       tps      rtps      wtps   bread/s   bwrtn/s
03:39:12 PM      0.00      0.00      0.00      0.00      0.00
03:39:13 PM      0.00      0.00      0.00      0.00      0.00
03:39:14 PM      0.00      0.00      0.00      0.00      0.00
03:39:15 PM      0.00      0.00      0.00      0.00      0.00
03:39:16 PM      0.00      0.00      0.00      0.00      0.00
Average:         0.00      0.00      0.00      0.00      0.00

pidstat

pidstat 指令可以幫助我們用來監控單一個 Session 的運作狀況。

首先透過 pg_stat_activity 這張系統表,找到對應正在執行的 Session 去確認他的 PID
也可以透過 pg_top 等工具來輔助檢視。
取得 PID 後就可以用 pidstat 指令來監控該連線的狀態
edb=# select * from pg_stat_activity where usename = 'enterprisedb';
-[ RECORD 1 ]----+---------------------------------------------------------------
.........
-[ RECORD 2 ]----+---------------------------------------------------------------
datid            | 16349
datname          | edb
pid              | 3858
leader_pid       |
usesysid         | 10
usename          | enterprisedb
application_name | psql
client_addr      |
client_hostname  |
client_port      | -1
backend_start    | 09-MAR-22 15:45:22.748634 +08:00
xact_start       |
query_start      | 09-MAR-22 15:47:05.556195 +08:00
state_change     | 09-MAR-22 15:47:05.556308 +08:00
wait_event_type  | Client
wait_event       | ClientRead
state            | idle
backend_xid      |
backend_xmin     |
query            | select 1;
backend_type     | client backend
-[ RECORD 3 ]----+---------------------------------------------------------------
..........

pidstat 指令用法
pidstat [選項] -p [指定Process PID] [計錄時間間隔(秒)]

選項
-l    顯示完整執行指令
-u   CPU使用狀況(預設顯示此項目)
-d   顯示 I/O
-r   記憶體使用狀況

使用範例
透過下面指令方式,
-u 顯示 CPU 
-l 顯示完整 command
-p 3858 指定 Process
2  兩秒顯示一次
由於 pidstat 本身無寫 Log 機制,只能用重新導向的方式來記錄後再觀察。
[root@localhost ~]# pidstat -u -l -p 3858 2
Linux 3.10.0-1160.el7.x86_64 (localhost.localdomain)    03/09/2022      _x86_64_        (4 CPU)

04:01:29 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
04:01:32 PM   998      3858    0.00    0.00    0.00    0.00     3  postgres: enterprisedb edb [local] idle
04:01:34 PM   998      3858    0.00    0.00    0.00    0.00     3  postgres: enterprisedb edb [local] idle
04:01:36 PM   998      3858    0.00    0.00    0.00    0.00     3  postgres: enterprisedb edb [local] idle