徳哥:PostgreSQL 实时健康监控大屏 - 高频指标

Posted ABCLink社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了徳哥:PostgreSQL 实时健康监控大屏 - 高频指标相关的知识,希望对你有一定的参考价值。

PostgreSQL

研究背景:最关键的一些数据库健康指标,趋势监测。


1
总连接数

主要看趋势,直接与业务量挂钩。

如果连接数接近 max_connection 水位,需要注意。

同时连接数应与数据库主机可用内存挂钩,每个连接保守估计 10MB 内存开销(这里还未计算 SYSCACHE,RELCACHE)。

select count(*) from pg_stat_activity ;  

演示,打印每秒的总连接数。

psql  
  
select count(*) from pg_stat_activity ;  
  
\watch 1  


2
N 秒内新建的连接数

主要看趋势,直接与业务量挂钩。

如果突发大量连接,可能是新增了业务服务器,或者是性能抖动过导致业务大量新建连接满足并发的请求。

突然连接数下降,可能原因是业务服务器突然释放连接,或者业务服务器挂了。

select count(*) from pg_stat_activity where now()-backend_start > '? second';  

演示,打印每秒的 5 秒内新建连接数。

psql  
  
select count(*) from pg_stat_activity where now()-backend_start > '5 second';  
  
\watch 1  


3
QPS

主要看趋势,直接与业务量挂钩。

QPS 指标来自 pg_stat_statements,由于这个插件有一个 STATEMENT 采集上限,可配置,例如最多采集 1000 条 SQL,如果有新的 SQL 被采集到时,并且 1000 已用完,则会踢掉最老的 SQL。所以我们这里统计的 QPS 并不是完全精确,不过还好PG内部会自动合并 SQL,把一些条件替换成变量,这样即使不使用绑定变量,也能追踪到很多 SQL。

对于业务 SQL 非常繁多并且大多数都是活跃 SQL 的场景,可以适当调大 pg_stat_statements 的 track 数,提高精准度。

除此之外,可以改进 pg_stat_statements 的功能,直接统计精准的 QPS。

with                                               
a as (select sum(calls) s, sum(case when ltrim(query,' ') ~* '^select' then calls else 0 end) q from pg_stat_statements),   
b as (select sum(calls) s, sum(case when ltrim(query,' ') ~* '^select' then calls else 0 end) q from pg_stat_statements , pg_sleep(1))   
select   
b.s-a.s,          -- QPS  
b.q-a.q,          -- 读QPS  
b.s-b.q-a.s+a.q   -- 写QPS  
from a,b;  

如果只想看 QPS,使用:

with                                               
a as (select sum(calls) s from pg_stat_statements),   
b as (select sum(calls) s from pg_stat_statements , pg_sleep(1))   
select   
b.s-a.s          -- QPS  
from a,b;  

演示,打印每秒的 QPS。

psql  
  
with                                               
a as (select sum(calls) s from pg_stat_statements),   
b as (select sum(calls) s from pg_stat_statements , pg_sleep(1))   
select   
b.s-a.s          -- QPS  
from a,b;  
  
\watch 0.000001  


4
标active session


主要看趋势,直接与业务量挂钩。

如果活跃会话数长时间超过 CPU 核数时,说明数据库响应变慢了,需要深刻关注。

select count(*) from pg_stat_activity where state='active';  

演示,打印每秒的活跃会话数。

psql  
  
select count(*) from pg_stat_activity where state='active';  
  
\watch 1  


5
平均 RT


活跃会话 /qps = RT(秒)


6
long query


当前系统中执行时间超过 N 秒的 SQL 有多少条,LONG QUERY 与活跃会话的比例说明当前 LONG SQL 的占比。占比越高,说明该系统可能偏向 OLAP,占比越低,说明该系统偏向 OLTP 业务。

select count(*) from pg_stat_activity where state='active' and now()-query_start > interval '? second';  

演示,打印每秒系统中执行时间超过 5 秒的 SQL 有多少条。

psql  
  
select count(*) from pg_stat_activity where state='active' and now()-query_start > interval '5 second';  
  
\watch 1  


7
long transaction


当前系统中 N 秒未结束的事务有多少条?

select count(*) from pg_stat_activity where now()-xact_start > interval '? second';  

演示,打印每秒系统中 5 秒未结束的事务有多少条:

psql  
  
select count(*) from pg_stat_activity where now()-xact_start > interval '5 second';  
  
\watch 1  


8
idle in transaction


当前系统中在事务中并且处于空闲状态的会话有多少,很多,说明业务端的处理可能比较慢,如果结合锁等待发现有大量锁等待,并且活跃会话数有突增,可能需要关注并排查业务逻辑的问题。

select count(*) from pg_stat_activity where state='idle in transaction';  

演示,打印每秒系统中在事务中并且处于空闲状态的会话有多少:

psql  
  
select count(*) from pg_stat_activity where state='idle in transaction';  
  
\watch 1  


9
long idle in transaction


当前系统中,有多少长期(超过 N 秒)处于空闲的事务。如果有较多这样的事务,说明业务端的处理时间超过N秒的情况非常普遍,应该尽快排查业务。

比如前端开启了游标,等待用户的翻页动作,用户可能开小差了。又比如业务上使用了一些交互模式,等用户的一些输入等。

这种情况应该尽量避免,否则长时间占用连接资源。

select count(*) from pg_stat_activity where state='idle in transaction' and now()-state_change > interval '? second';  

演示,打印每秒系统中在事务中并且处于空闲状态(超过 5 秒)的会话有多少:

psql  
  
select count(*) from pg_stat_activity where state='idle in transaction' and now()-state_change > interval '5 second';  
  
\watch 1  


10
waiting


当前系统中,处于等待中的会话有多少。

如果很多,说明出现了大量的锁等待,使用末尾文章进行排查。

select count(*) from pg_stat_activity where wait_event_type is not null;  

演示,打印每秒系统中处于等待中的会话有多少。

psql  
  
select count(*) from pg_stat_activity where wait_event_type is not null;  
  
\watch 1  


11
long waiting


当前系统中,等待超过N秒的会话有多少。

select count(*) from pg_stat_activity where wait_event_type is not null and now()-state_change > interval '? second';  

演示,打印每秒系统中等待超过 5 秒的会话有多少。

psql  
  
select count(*) from pg_stat_activity where wait_event_type is not null and now()-state_change > interval '5 second';  
  
\watch 1  


12
2pc


当前系统中,2PC 的事务有多少。如果接近 max_prepared_transactions,需要注意。建议调大 max_prepared_transactions,或者排查业务是否未及时提交。

select count(*) from pg_prepared_xacts;  

演示,打印每秒系统中未结束的 2PC 事务数。

psql  
  
select count(*) from pg_prepared_xacts;  
  
\watch 1  


13
long 2pc


当前系统中,超过N秒未结束的 2PC 的事务有多少。如果很多,需要排查业务为什么未及时提交。

select count(*) from pg_prepared_xacts where now() - prepared > interval '? second';   

演示,打印每秒系统中 5 秒仍未结束的 2PC 事务数。

psql  
  
select count(*) from pg_prepared_xacts where now() - prepared > interval '5 second';   
  
\watch 1  


14
膨胀点监测


多久以前的垃圾可以被回收?

时间间隔越大,说明越容易导致膨胀。

排查这几个方向,长事务,长 SQL,2PC,持有 SNAPSHOT 的 QUERY。必要时把不合理的老的会话干掉。

with a as 
(select min(xact_start) m from pg_stat_activity where backend_xid is not null or backend_xmin is not null), 
b as (select min(prepared) m from pg_prepared_xacts) 
select now()-least(a.m,b.m) from a,b;  

演示,打印每秒系统中多久以前的垃圾可以被回收:

psql  
  
with a as 
(select min(xact_start) m from pg_stat_activity where backend_xid is not null or backend_xmin is not null), 
b as (select min(prepared) m from pg_prepared_xacts) 
select now()-least(a.m,b.m) from a,b;  
  
\watch 1  


15
空间


看当前占用情况,打快照,看时间维度空间变化情况。

按库划分:

postgres=# \l+  
                                                                   List of databases  
   Name    |  Owner   | Encoding  |  Collate   |   Ctype    |   Access privileges   |  Size   | Tablespace |                Description                   
-----------+----------+-----------+------------+------------+-----------------------+---------+------------+--------------------------------------------  
 postgres  | postgres | SQL_ASCII | en_US.UTF8 | en_US.UTF8 |                       | 54 GB   | pg_default | default administrative connection database  
 template0 | postgres | SQL_ASCII | en_US.UTF8 | en_US.UTF8 | =c/postgres          +| 7489 kB | pg_default | unmodifiable empty database  
           |          |           |            |            | postgres=CTc/postgres |         |            |   
 template1 | postgres | SQL_ASCII | en_US.UTF8 | en_US.UTF8 | =c/postgres          +| 578 MB  | pg_default | default template for new databases  
           |          |           |            |            | postgres=CTc/postgres |         |            |   
 test      | test     | SQL_ASCII | en_US.UTF8 | en_US.UTF8 |                       | 7489 kB | pg_default |   
(4 rows)  

按表空间划分:

postgres=# \db+  
                                                    List of tablespaces  
        Name        |  Owner   |               Location               | Access privileges | Options |  Size   | Description   
--------------------+----------+--------------------------------------+-------------------+---------+---------+-------------  
 dbt2_index1        | postgres | /data02/pg/tbs_tpcc/index1/ts        |                   |         | 452 MB  |   
 dbt2_index2        | postgres | /data02/pg/tbs_tpcc/index2/ts        |                   |         | 869 MB  |   
 dbt2_pk_customer   | postgres | /data02/pg/tbs_tpcc/pk_customer/ts   |                   |         | 451 MB  |   
 dbt2_pk_district   | postgres | /data02/pg/tbs_tpcc/pk_district/ts   |                   |         | 236 kB  |   
 dbt2_pk_item       | postgres | /data02/pg/tbs_tpcc/pk_item/ts       |                   |         | 2212 kB |   
 dbt2_pk_new_order  | postgres | /data02/pg/tbs_tpcc/pk_new_order/ts  |                   |         | 149 MB  |   
 dbt2_pk_order_line | postgres | /data02/pg/tbs_tpcc/pk_order_line/ts |                   |         | 4701 MB |   
 dbt2_pk_orders     | postgres | /data02/pg/tbs_tpcc/pk_orders/ts     |                   |         | 490 MB  |   
 dbt2_pk_stock      | postgres | /data02/pg/tbs_tpcc/pk_stock/ts      |                   |         | 1768 MB |   
 dbt2_pk_warehouse  | postgres | /data02/pg/tbs_tpcc/pk_warehouse/ts  |                   |         | 44 kB   |   
 pg_default         | postgres |                                      |                   |         | 46 GB   |   
 pg_global          | postgres |                                      |                   |         | 573 kB  |   
(12 rows)  


16
数据空间


数据占用的空间。


17
日志空间


WAL 日志占用的空间。


18
备库发送延迟


select application_name,client_addr,client_hostname,client_port,state,sync_priority,sync_state,pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), sent_lsn)) from pg_stat_replication;  


19
备库 APPLY 延迟


select application_name,client_addr,client_hostname,client_port,state,sync_priority,sync_state,pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lag)) from pg_stat_replication;  


20
SLOT 延迟


select slot_name, plugin, slot_type, temporary, active, active_pid, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn)) from pg_replication_slots;  


21
归档延迟


最后一次归档失败时间减去最后一次归档成功的时间,求时间差

select last_failed_time - last_archived_time from pg_stat_archiver;  


22
数据库活动信息


以下都可以针对单个数据库输出,也可以输出整个实例的统计。

postgres=# \d pg_stat_database  
                     View "pg_catalog.pg_stat_database"  
     Column     |           Type           | Collation | Nullable | Default   
----------------+--------------------------+-----------+----------+---------  
 datid          | oid                      |           |          |   
 datname        | name                     |           |          |   
 numbackends    | integer                  |           |          |   
 xact_commit    | bigint                   |           |          |   
 xact_rollback  | bigint                   |           |          |   
 blks_read      | bigint                   |           |          |   
 blks_hit       | bigint                   |           |          |   
 tup_returned   | bigint                   |           |          |   
 tup_fetched    | bigint                   |           |          |   
 tup_inserted   | bigint                   |           |          |   
 tup_updated    | bigint                   |           |          |   
 tup_deleted    | bigint                   |           |          |   
 conflicts      | bigint                   |           |          |   
 temp_files     | bigint                   |           |          |   
 temp_bytes     | bigint                   |           |          |   
 deadlocks      | bigint                   |           |          |   
 blk_read_time  | double precision         |           |          |   
 blk_write_time | double precision         |           |          |   
 stats_reset    | timestamp with time zone |           |          |   


23
每秒事务提交数


多次查询计算:

select sum(xact_commit) from pg_stat_database;  -- pg_stat_get_db_xact_commit 为stable函数,一个事务中两次调用之间只执行一次,所以需要外部多次执行。  


24
每秒事务回滚数


select sum(xact_rollback) from pg_stat_database;   


25
每秒全表扫描记录数


select sum(tup_returned) from pg_stat_database;   


26
每秒索引扫描回表记录数


select sum(tup_fetched) from pg_stat_database;   


27
每秒插入记录数


select sum(tup_inserted) from pg_stat_database;   


28
每秒更新记录数


select sum(tup_updated) from pg_stat_database;   


29
每秒删除记录数


select sum(tup_deleted) from pg_stat_database;   


30
备库查询冲突数


select sum(conflicts) from pg_stat_database;   


31
死锁数


select sum(deadlocks) from pg_stat_database;   


徳哥:PostgreSQL 实时健康监控大屏 - 高频指标


分享人介绍 :

徳哥,原名周正中,任职于阿里云数据库团队,数据库架构师。是中国开源软件推进联盟 PostgreSQL 分会,特聘资深领域专家;PostgreSQL 中国社区发起人之一、常委、兼任社区大学校长。同时还是 DBGeeK 联盟专家团成员,拥有 30 项数据库专利。



ABCLink 社区

人工智能  大数据  云计算



技术 | 管理 | 分享 | 互助

以上是关于徳哥:PostgreSQL 实时健康监控大屏 - 高频指标的主要内容,如果未能解决你的问题,请参考以下文章

货物监控技术助力疫苗运输温度实时监管,为人民生命健康保驾护航

基于 Echarts + Python 动态实时大屏真棒

使用 LISTEN 和 NOTIFY(或 Node JS)实时监控 Postgresql 查询更改的任何方法?

业务实时监控服务概述

有没有实际案例说明可视化大屏的需求趋势的内容?

可视化大屏是啥