PostgreSQL 常用监控指标

秒速五厘米 2024-03-24 14:25 210阅读 0赞

背景

最关键的一些数据库健康指标,趋势监测。

1 总连接数

主要看趋势,直接与业务量挂钩
如果连接数接近max_connection水位,需要注意。
同时连接数应与数据库主机可用内存挂钩,每个连接保守估计10MB内存开销(这里还未计算SYSCACHE,RELCACHE)。

  1. select count(*) from pg_stat_activity ;

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

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

2 N秒内新建的连接数

主要看趋势,直接与业务量挂钩
如果突发大量连接,可能是新增了业务服务器,或者是性能抖动过导致业务大量新建连接满足并发的请求。
突然连接数下降,可能原因是业务服务器突然释放连接,或者业务服务器挂了。

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

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

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

3 SQL活跃统计

1、需要加载pg_stat_statements,如果需要跟踪IO时间,需要开启track_io_timing。
同时需要注意,由于pg_stat_statements跟踪的SQL有限,最近未访问过的SQL的跟踪信息可能被抛弃。所以统计并不是非常的精准。

  1. postgres=# \d pg_stat_statements
  2. View "public.pg_stat_statements"
  3. Column | Type | Collation | Nullable | Default
  4. ---------------------+------------------+-----------+----------+---------
  5. userid | oid | | |
  6. dbid | oid | | |
  7. queryid | bigint | | |
  8. query | text | | |
  9. calls | bigint | | |
  10. total_time | double precision | | |
  11. min_time | double precision | | |
  12. max_time | double precision | | |
  13. mean_time | double precision | | |
  14. stddev_time | double precision | | |
  15. rows | bigint | | |
  16. shared_blks_hit | bigint | | |
  17. shared_blks_read | bigint | | |
  18. shared_blks_dirtied | bigint | | |
  19. shared_blks_written | bigint | | |
  20. local_blks_hit | bigint | | |
  21. local_blks_read | bigint | | |
  22. local_blks_dirtied | bigint | | |
  23. local_blks_written | bigint | | |
  24. temp_blks_read | bigint | | |
  25. temp_blks_written | bigint | | |
  26. blk_read_time | double precision | | |
  27. blk_write_time | double precision | | |

3.1 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。
主要看趋势,直接与业务量挂钩

  1. with
  2. a as (select sum(calls) s, sum(case when ltrim(query,' ') ~* '^select' then calls else 0 end) q from pg_stat_statements),
  3. 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))
  4. select
  5. b.s-a.s, -- QPS
  6. b.q-a.q, -- QPS
  7. b.s-b.q-a.s+a.q -- QPS
  8. from a,b;

如果只想看QPS,使用

  1. with
  2. a as (select sum(calls) s from pg_stat_statements),
  3. b as (select sum(calls) s from pg_stat_statements , pg_sleep(1))
  4. select
  5. b.s-a.s -- QPS
  6. from a,b;

演示,打印每秒的QPS。

  1. psql
  2. with
  3. a as (select sum(calls) s from pg_stat_statements),
  4. b as (select sum(calls) s from pg_stat_statements , pg_sleep(1))
  5. select
  6. b.s-a.s -- QPS
  7. from a,b;
  8. \watch 0.000001

3.2 每秒处理了多少行

每秒处理了多少行,包括写入,读取,更新,删除等操作。

  1. 两次快照相减除以时间间隔
  2. sum(pg_stat_statements.rows)

3.3 共享缓冲区:每秒缓存命中、未命中读

  1. shared_blks_hit | bigint | | |
  2. shared_blks_read | bigint | | |

3.4 共享缓冲区:每秒产生多少脏页

  1. shared_blks_dirtied | bigint | | |

3.5 共享缓冲区:每秒异步write多少脏页

  1. shared_blks_written | bigint | | |

3.6 进程本地缓冲区:每秒缓存命中、未命中读

  1. local_blks_hit | bigint | | |
  2. local_blks_read | bigint | | |

3.7 进程本地缓冲区:每秒产生多少脏页

  1. local_blks_dirtied | bigint | | |

3.8 进程本地缓冲区:每秒异步write多少脏页

  1. local_blks_written | bigint | | |

3.9 临时文件每秒读

  1. temp_blks_read | bigint | | |

3.10 临时文件每秒写

  1. temp_blks_written | bigint | | |

3.11 两次快照之间的读数据块耗时

  1. blk_read_time | double precision | | |

3.12 两次快照之间的写数据块耗时

  1. blk_write_time | double precision | | |

4 active session

主要看趋势,直接与业务量挂钩
如果活跃会话数长时间超过CPU核数时,说明数据库响应变慢了,需要深刻关注。

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

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

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

5 平均RT

活跃会话/qps = RT(秒)

6 long query

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

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

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

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

7 long transaction

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

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

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

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

8 idle in transaction

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

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

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

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

9 long idle in transaction

当前系统中,有多少长期(超过N秒)处于空闲的事务。如果有较多这样的事务,说明业务端的处理时间超过N秒的情况非常普遍,应该尽快排查业务。
比如前端开启了游标,等待用户的翻页动作,用户可能开小差了。又比如业务上使用了一些交互模式,等用户的一些输入等。
这种情况应该尽量避免,否则长时间占用连接资源。

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

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

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

10 waiting

当前系统中,处于等待中的会话有多少。
如果很多,说明出现了大量的锁等待,使用末尾文章进行排查。

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

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

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

11 long waiting

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

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

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

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

12 2pc

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

  1. select count(*) from pg_prepared_xacts;

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

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

13 long 2pc

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

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

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

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

14 膨胀点监测 - 多久以前的垃圾可以被回收

时间间隔越大,说明越容易导致膨胀。
排查这几个方向,长事务,长SQL,2PC,持有SNAPSHOT的QUERY。必要时把不合理的老的会话干掉。

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

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

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

15 空间

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

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

按表空间划分

  1. postgres=# \db+
  2. List of tablespaces
  3. Name | Owner | Location | Access privileges | Options | Size | Description
  4. --------------------+----------+--------------------------------------+-------------------+---------+---------+-------------
  5. dbt2_index1 | postgres | /data02/pg/tbs_tpcc/index1/ts | | | 452 MB |
  6. dbt2_index2 | postgres | /data02/pg/tbs_tpcc/index2/ts | | | 869 MB |
  7. dbt2_pk_customer | postgres | /data02/pg/tbs_tpcc/pk_customer/ts | | | 451 MB |
  8. dbt2_pk_district | postgres | /data02/pg/tbs_tpcc/pk_district/ts | | | 236 kB |
  9. dbt2_pk_item | postgres | /data02/pg/tbs_tpcc/pk_item/ts | | | 2212 kB |
  10. dbt2_pk_new_order | postgres | /data02/pg/tbs_tpcc/pk_new_order/ts | | | 149 MB |
  11. dbt2_pk_order_line | postgres | /data02/pg/tbs_tpcc/pk_order_line/ts | | | 4701 MB |
  12. dbt2_pk_orders | postgres | /data02/pg/tbs_tpcc/pk_orders/ts | | | 490 MB |
  13. dbt2_pk_stock | postgres | /data02/pg/tbs_tpcc/pk_stock/ts | | | 1768 MB |
  14. dbt2_pk_warehouse | postgres | /data02/pg/tbs_tpcc/pk_warehouse/ts | | | 44 kB |
  15. pg_default | postgres | | | | 46 GB |
  16. pg_global | postgres | | | | 573 kB |
  17. (12 rows)

16 数据空间

数据占用的空间。

17 日志空间

WAL日志占用的空间。

18 备库发送延迟

  1. 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延迟

  1. 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 延迟

  1. 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 归档延迟

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

  1. select last_failed_time - last_archived_time from pg_stat_archiver;

22 数据库活动信息

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

  1. postgres=# \d pg_stat_database
  2. View "pg_catalog.pg_stat_database"
  3. Column | Type | Collation | Nullable | Default
  4. ----------------+--------------------------+-----------+----------+---------
  5. datid | oid | | |
  6. datname | name | | |
  7. numbackends | integer | | |
  8. xact_commit | bigint | | |
  9. xact_rollback | bigint | | |
  10. blks_read | bigint | | |
  11. blks_hit | bigint | | |
  12. tup_returned | bigint | | |
  13. tup_fetched | bigint | | |
  14. tup_inserted | bigint | | |
  15. tup_updated | bigint | | |
  16. tup_deleted | bigint | | |
  17. conflicts | bigint | | |
  18. temp_files | bigint | | |
  19. temp_bytes | bigint | | |
  20. deadlocks | bigint | | |
  21. blk_read_time | double precision | | |
  22. blk_write_time | double precision | | |
  23. stats_reset | timestamp with time zone | | |

22.1 每秒事务提交数

多次查询计算

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

22.2 每秒事务回滚数

  1. select sum(xact_rollback) from pg_stat_database;

22.3 每秒全表扫描记录数

  1. select sum(tup_returned) from pg_stat_database;

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

  1. select sum(tup_fetched) from pg_stat_database;

22.5 每秒插入记录数

  1. select sum(tup_inserted) from pg_stat_database;

22.6 每秒更新记录数

  1. select sum(tup_updated) from pg_stat_database;

22.7 每秒删除记录数

  1. select sum(tup_deleted) from pg_stat_database;

22.8 备库查询冲突数

  1. select sum(conflicts) from pg_stat_database;

22.9 死锁数

  1. select sum(deadlocks) from pg_stat_database;

发表评论

表情:
评论列表 (有 0 条评论,210人围观)

还没有评论,来说两句吧...

相关阅读

    相关 房地产指标

    以最近五年商品住宅用地规模,扣除最近五年商品住宅成交规模计算广义库存,以最近三年商品住宅年均成交量计,衡量各城市库存风险。 以2013-2017年年均成交量为参照标准