1. 程式人生 > >PostgreSQL監控指標

PostgreSQL監控指標

資料庫狀態資訊

資料庫狀態資訊主要體現資料庫的當前狀態

1.目前客戶端的連線數

postgres=# SELECT count(*) FROM pg_stat_activity WHERE NOT pid=pg_backend_pid();

2.連線狀態

postgres=# SELECT pid,waiting,current_timestamp - least(query_start,xact_start) AS runtime,substr(query,1,25) AS current_query 
FROM pg_stat_activity WHERE NOT pid=
pg_backend_pid(); pid | waiting | runtime | current_query ------+---------+-----------------+----------------------- 9381 | f | 00:01:24.425487 | select * from orders;

可以檢視每個連線的pid,執行的操作,是否發生等待,根據查詢,或者事務統計開始時間等等。有多少個連結查詢就有多少行 所以可以用order by,limit限制查詢行數

3.資料庫佔用空間

postgres=# select pg_size_pretty
(pg_database_size('postgres'));

一個數據庫資料檔案對應儲存在以這個資料庫PID命名的檔案中,通過統計所有以PID命名檔案的總大小,也可以得出這個資料庫佔用的空間。

表佔用的空間使用pg_relation_size()查詢,對應的系統中的檔名和pg_class中的filenode相同,一個熱點的表最好一天一統計大小,獲得表的一個增長狀況,來預測資料庫未來可能的增長狀況。根據需求提前準備空間應付資料庫的增長。

4.等待事件

postgres# SELECT bl.pid AS blocked_pid, a.usename AS blocked_user,
kl.pid AS blocking_pid, ka.usename AS blocking_user, a.query AS blocked_statement FROM pg_locks bl JOIN pg_stat_activity a ON a.pid = bl.pid JOIN pg_locks kl ON kl.transactionid = bl.transactionid AND kl.pid != bl.pid JOIN pg_stat_activity ka ON ka.pid = kl.pid WHERE NOT bl.granted;

根據阻塞的語句的會話PID做相應處理

資料庫統計資訊

1.sql語句統計

實現上述統計需要安裝一個pg的extension:pg_stat_statements–1.1.sql,調整postgres.conf:shared_preload_libraries = 'pg_stat_statements',就可以使用了

postgres=# SELECT calls, total_time, rows, 100.0 * shared_blks_hit /nullif(shared_blks_hit + shared_blks_read, 0) AS hit_percent,substr(query,1,25)
FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;
calls  | total_time | rows | hit_percent          | substr 
-------+------------+------+----------------------+---------------------------
1      | 23.104     | 17   | 99.4974874371859296  | SELECT n.nspname as Sche
1      | 21.808     | 2    |                      | select * from pg_stat_sta
2      | 5.391      | 2    |                      | SELECT name FROM (SELECT
3      | 3.307      | 57   | 100.0000000000000000 | SELECT pg_catalog.quote_i
4      | 1.318      | 19   | 100.0000000000000000 | SELECT calls, total_time,

上述查詢是按照查詢的執行時間來排序的,可以定位執行比較慢的sql,也可以用來查出常用sql,以及sql共享記憶體的命中率等資訊

2.表的共享記憶體的利用情況統計

實現上述統計需要安裝一個pg的extension:pg_buffercache–1.0.sql

postgres=# SELECT c.relname, count(*) AS buffers 
FROM pg_buffercache b INNER JOIN pg_class c ON b.relfilenode = pg_relation_filenode(c.oid) 
AND b.reldatabase IN (0, (SELECT oid FROM pg_database WHERE datname = current_database())) GROUP BY c.relname ORDER BY 2 DESC LIMIT 5;
relname                         | buffers 
--------------------------------+---------
pg_proc                         | 28
pg_attribute                    | 23
pg_operator                     | 14
pg_proc_proname_args_nsp_index  | 10
pg_class                        | 9

表在共享記憶體中佔用的塊數,用來查看錶是不是在記憶體中,buffers的單位是資料塊,預設8K,如果計算大小等於表的大小,說明全表的資料都在快取中,這時的查詢速度是很快的

3.對一個表執行操作的統計

實現統計對一個表操作的偏重,insert,update,delete的比率

postgres=# update products set price=11.00 where prod_id=30;
UPDATE 1
postgres=# delete from products where prod_id=30;
DELETE 1
postgres=# SELECT relname,cast(n_tup_ins AS numeric) / (n_tup_ins + n_tup_upd + n_tup_del) AS ins_pct,
cast(n_tup_upd AS numeric) / (n_tup_ins + n_tup_upd + n_tup_del) AS upd_pct, 
cast(n_tup_del AS numeric) / (n_tup_ins + n_tup_upd + n_tup_del) AS del_pct 
FROM pg_stat_user_tables where relname='products';
relname   | ins_pct                | upd_pct                | del_pct 
----------+------------------------+------------------------+------------------------
products  | 0.00000000000000000000 | 0.50000000000000000000 | 0.50000000000000000000

4.表的IO和索引的IO

表的IO主要涉及查詢的時候查詢的邏輯塊和物理塊,歸到底也是命中率的問題,當然最簡單的思維方式,一張表存在記憶體中的內容越多,相應的查詢速度越快。相關檢視:pg_stat_user_tables

相對於表的大小來說,索引佔用的空間要小的多,所以常用的表,可以讓其索引一直存在記憶體中,很多時候保持索引的一個高命中率是非常必要的。相關檢視:pg_stat_user_indexes

postgres# SELECT indexrelname,cast(idx_blks_hit as numeric) / (idx_blks_hit + idx_blks_read) AS hit_pct,
idx_blks_hit,idx_blks_read 
FROM pg_statio_user_indexes WHERE (idx_blks_hit + idx_blks_read)>0 ORDER BY hit_pct;

5.buffer background 和 checkpoint

涉及檢查點寫和後臺寫的比率問題,檢查點的集中資料寫入會對資料庫IO的效能有很大的提升,但相應的需要部分空間儲存髒資料,而且一旦資料庫崩潰,記憶體中未被寫入磁碟的髒資料越多,資料庫恢復時間也就越長,這是一個數據庫的平衡問題,相關問題在調優文件中做深入研究。 相關檢視:pg_stat_bgwriter

postgres=# SELECT
(100 * checkpoints_req) / (checkpoints_timed + checkpoints_req) AS checkpoints_req_pct,
pg_size_pretty(buffers_checkpoint * block_size / (checkpoints_timed + checkpoints_req)) AS avg_checkpoint_write,
pg_size_pretty(block_size * (buffers_checkpoint + buffers_clean + buffers_backend)) AS total_written,
100 * buffers_checkpoint / (buffers_checkpoint + buffers_clean + buffers_backend) AS checkpoint_write_pct,
100 * buffers_backend / (buffers_checkpoint + buffers_clean + buffers_backend) AS backend_write_pct,*
FROM pg_stat_bgwriter,(SELECT cast(current_setting('block_size') AS integer) AS block_size) AS bs;

系統監控資訊

介紹一些關於資料庫需要檢視的系統狀態資訊

1.資料庫基本狀態資訊

# ps -ef | grep postgres
# netstat -altunp | grep 5432
# pg_controdata   

pg_controdata命令和psql同在postgres的bin目錄下,系統命令下查詢到最全面的資料庫快照資訊

2.top動態資訊配合其他命令使用(擷取相關行)

# top -u postgres
Cpu(s): 1.7%us, 1.0%sy, 0.0%ni, 97.3%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 2051164k total, 1476536k used, 574628k free, 239624k buffers
Swap: 2097144k total, 0k used, 2097144k free, 768676k cached
PID   USER    PR NI VIRT RES SHR   S %CPU %MEM TIME+ COMMAND 
11172 postgres 20 0 709m 34m 33m   S 0.0  1.7 0:00.79 postgres 
9380  postgres 20 0 167m 5284 2272 S 0.0  0.3 0:00.05 psql 
11178 postgres 20 0 709m 5168 4408 S 0.0  0.3 0:00.01 postgres 
11179 postgres 20 0 709m 4656 3920 S 0.0  0.2 0:00.01 postgres 
# free
total used free shared buffers cached
Mem: 2051164 1476032 575132 0 239624 768676
-/+ buffers/cache: 467732 1583432
Swap: 2097144 0 2097144
# iotop -u postgres
Total DISK READ: 0.00 B/s | Total DISK WRITE: 0.00 B/s
11175 be/4 postgres 0.00 B/s 0.00 B/s 0.00 % 0.00 % postgres: logger process
11181 be/4 postgres 0.00 B/s 0.00 B/s 0.00 % 0.00 % postgres: autovacuum launcher process
11178 be/4 postgres 0.00 B/s 0.00 B/s 0.00 % 0.00 % postgres: checkpointer process
11180 be/4 postgres 0.00 B/s 0.00 B/s 0.00 % 0.00 % postgres: wal writer process
11182 be/4 postgres 0.00 B/s 0.00 B/s 0.00 % 0.00 % postgres: stats collector process
11179 be/4 postgres 0.00 B/s 0.00 B/s 0.00 % 0.00 % postgres: writer process

簡單分析下top命令,用top可以分析出系統的當前總體的負載狀況,如上例,總體負載率很低,在io等待率高的時候可以使用iotop來定位io具體的程序,top中的VIRT RES 可以看出程序希望獲取的記憶體,和佔用系統記憶體的數量,可以根據來判定系統記憶體的分配情況,記憶體的值也關聯到一些引數的設定,如postgres在發生檢查點之前checkpointer process程序會消耗比較大的實體記憶體,直到檢查點發生後,佔用的記憶體才會被釋放掉,所以在設定檢查點時間的時候也要將記憶體的佔用考慮進去。

free總體的表現記憶體的使用情況,buffers和cached在應用申請記憶體的時候會被系統釋放掉,所以應用實際可以使用的記憶體是free的值加上buffers和cached的。

3.sar做輔助分析

sar類似於快照的方式來儲存系統過去的資訊

# sar
03:40:01 PM CPU %user %nice %system %iowait %steal %idle
03:50:01 PM all 1.56  0.00  0.68    0.10    0.00   97.67
04:00:02 PM all 1.91  0.00  0.63    0.05    0.00   97.41
Average:    all 1.07  0.04  1.95    2.65    0.00   94.29
# sar -r
12:40:01 PM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit
12:50:01 PM 567124    1484040   72.35    237596    755720   1426740  34.39
01:10:01 PM 567256    1483908   72.34    237600    755720   1426740  34.39
01:20:01 PM 567132    1484032   72.35    237600    755724   1426740  34.39
Average:    742177    1308987   63.82    195809    669444   1390037  33.51

這些統計資訊可以對照效能問題,檢視當時的系統狀態。