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
這些統計資訊可以對照效能問題,檢視當時的系統狀態。