mirror of
https://github.com/Vonng/ddia.git
synced 2024-12-06 15:20:12 +08:00
199 lines
12 KiB
Markdown
199 lines
12 KiB
Markdown
# Monitor
|
||
|
||
## 磁盘
|
||
|
||
### 磁盘写满问题
|
||
|
||
* 一个数据库管理员最重要的磁盘监控任务就是确保磁盘不会写满。
|
||
* 一个写满了的数据磁盘可能不会导致数据的崩溃,但它肯定会让系统变得不可用。
|
||
* 如果保存 WAL 文件的磁盘变满,Server会产生致命错误,可能会关闭。
|
||
* 有些文件系统在快满的时候性能会急剧恶化,不要等到磁盘完全满时再行动。
|
||
* 可以将WAL和数据目录放到不同的磁盘上。
|
||
* 可以通过使用表空间(Tablespace)把一些数据库文件移到其他文件系统上去。
|
||
|
||
### 磁盘占用
|
||
|
||
* 每个表都有一个主要的堆磁盘文件,大多数数据都存储在其中。
|
||
* 每个表和索引都存放在单独的磁盘文件里。若超过 1G 字节,则可能多于一个文件。
|
||
* 如果一个表有很宽(>2KB)的列, 则存在一个TOAST文件之关联, 用于存储太宽的值。因为Pg里一个页大小8KB,而单个元组不允许跨页,TOAST字段长度用四字节整形表示,最高的两个比特位用于指示Toast,所以单个字段值长度不能超过1G。
|
||
|
||
### 监视磁盘
|
||
|
||
有三种方式监控磁盘空间:
|
||
|
||
* 人工观察系统目录。`du`, `df -h`
|
||
|
||
* 使用`oid2name`模块
|
||
|
||
* 使用`SQL`函数与系统视图。(推荐)
|
||
|
||
例如`pg_class`中的`RelPages`指明了对象使用的Page (8k block)的数目。可用于预估表大小。
|
||
|
||
|
||
### 常用查询
|
||
|
||
```plsql
|
||
--查询表占用空间(估计)
|
||
-- 页面大小为8k,元组条数为估计值
|
||
SELECT relname, relpages, reltuples,
|
||
pg_relation_filepath(oid), reltoastrelid
|
||
FROM pg_class where relname = 'messages';
|
||
|
||
-- 查看表索引大小
|
||
SELECT c2.relname, c2.relpages
|
||
FROM pg_class c, pg_class c2, pg_index i
|
||
WHERE c.relname = 'messages' AND
|
||
c.oid = i.indrelid AND
|
||
c2.oid = i.indexrelid
|
||
ORDER BY c2.relname DESC;
|
||
|
||
-- 查看表大小与索引大小
|
||
SELECT
|
||
relname,
|
||
relpages,
|
||
reltuples,
|
||
pg_relation_filepath(oid),
|
||
pg_size_pretty(pg_relation_size(oid)) AS rel_size,
|
||
pg_size_pretty(pg_indexes_size(oid)) AS idx_size,
|
||
reltoastrelid
|
||
FROM pg_class
|
||
WHERE relname = 'poi';
|
||
```
|
||
|
||
|
||
|
||
## 锁
|
||
|
||
未解决的锁可以通过系统视图 `pg_locks`查看
|
||
|
||
|
||
|
||
## Vacuum进度
|
||
|
||
目前只有Vacuum命令可以查看执行进度。
|
||
|
||
```bash
|
||
pg_stat_progress_vacuum
|
||
```
|
||
|
||
|
||
|
||
|
||
|
||
## 指标
|
||
|
||
### 进程监控
|
||
|
||
使用Unix工具,可以查看工作中的postgres进程
|
||
|
||
```bash
|
||
ps auxww | grep ^postgres
|
||
```
|
||
|
||
```bash
|
||
$ ps auxww | grep ^postgres
|
||
postgres 15551 0.0 0.1 57536 7132 pts/0 S 18:02 0:00 postgres -i
|
||
postgres 15554 0.0 0.0 57536 1184 ? Ss 18:02 0:00 postgres: writer process
|
||
postgres 15555 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: checkpointer process
|
||
postgres 15556 0.0 0.0 57536 916 ? Ss 18:02 0:00 postgres: wal writer process
|
||
postgres 15557 0.0 0.0 58504 2244 ? Ss 18:02 0:00 postgres: autovacuum launcher process
|
||
postgres 15558 0.0 0.0 17512 1068 ? Ss 18:02 0:00 postgres: stats collector process
|
||
postgres 15582 0.0 0.0 58772 3080 ? Ss 18:04 0:00 postgres: joe runbug 127.0.0.1 idle
|
||
postgres 15606 0.0 0.0 58772 3052 ? Ss 18:07 0:00 postgres: tgl regression [local] SELECT waiting
|
||
postgres 15610 0.0 0.0 58772 3056 ? Ss 18:07 0:00 postgres: tgl regression [local] idle in transaction
|
||
```
|
||
|
||
例如,空连接会提示`[idle]`,`begin`的事务会提示`idle in transaction`,如果进程在执行某条命令,会显示在进程的名称之中。
|
||
|
||
其他实用的监控工具包括:`ps`,`top`,`iostat`,`vmstat`
|
||
|
||
|
||
|
||
## 统计收集
|
||
|
||
### 相关选项
|
||
|
||
| name | type | default | comment |
|
||
| ---------------------------- | ---------- | ------------- | -------------------------------------- |
|
||
| `track_activities` | `boolean` | `true` | 启用对每个会话的当前执行命令的信息收集,还有命令开始执行的时间 |
|
||
| ` track_activity_query_size` | ` integer` | `1024` | 声明保留的字节数,以跟踪每个活动会话的当前执行命令 |
|
||
| ` track_counts` | `boolean` | `true` | 启用在数据库活动上的统计收集,Vacuum需要这个统计 |
|
||
| ` track_io_timing` | `boolean` | `false` | 启用对系统 I/O 调用的计时。 |
|
||
| ` track_functions` | `enum` | `none` | 指定`pl`只跟踪过程语言函数,指定`all`跟踪 SQL 和 C 语言函数 |
|
||
| ` stats_temp_directory` | `string` | `pg_stat_tmp` | 统计数据临时目录路径 |
|
||
|
||
* 统计进程通过临时文件将统计数据传递给其他PostgreSQL进程
|
||
* 临时的统计信息放在`pg_stat_tmp`目录下,这个目录可以通过RAMDISK获得更好的性能。
|
||
* 当服务器关闭时,统计数据的拷贝会放在`pg_stat`目录下。
|
||
* 当服务器启动恢复时,所有统计计数器会重置。
|
||
|
||
|
||
|
||
### 查看统计数据
|
||
|
||
* 统计数据并非实时更新的,每个服务进程只有在闲置前会更新统计计数。所以正在执行的查询和事务不影响计数。
|
||
* 收集器本身每隔(PGSTAT_STAT_INTERVAL=500ms)才发送一次新的报告。所以除了 当前进程活动`track_activity`之外的统计指标都不是最新的。
|
||
* 在事务中执行的统计查询,统计数据不会发生变化。使用`pg_stat_clear_snapshot()`来获取最新的快照。
|
||
|
||
### 系统视图名称
|
||
|
||
| 视图名称 | 描述 |
|
||
| ----------------------------- | ---------------------------------------- |
|
||
| `pg_stat_archiver` | 只有一行,显示有关 WAL 归档进程活动的统计信息。详见[pg_stat_archiver](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-ARCHIVER-VIEW)。 |
|
||
| `pg_stat_bgwriter` | 只有一行,显示有关后台写进程的活动的统计信息。详见[pg_stat_bgwriter](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-BGWRITER-VIEW)。 |
|
||
| `pg_stat_database` | 每个数据库一行,显示数据库范围的统计信息。详见[pg_stat_database](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-DATABASE-VIEW)。 |
|
||
| `pg_stat_database_conflicts` | 每个数据库一行,显示数据库范围的统计信息, 这些信息的内容是关于由于与后备服务器的恢复过程 发生冲突而被取消的查询。详见[pg_stat_database_conflicts](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-DATABASE-CONFLICTS-VIEW)。 |
|
||
| `pg_stat_all_tables` | 当前数据库中每个表一行,显示有关访问指定表的统计信息。详见[pg_stat_all_tables](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-ALL-TABLES-VIEW)。 |
|
||
| `pg_stat_sys_tables` | 和`pg_stat_all_tables`一样,但只显示系统表。 |
|
||
| `pg_stat_user_tables` | 和`pg_stat_all_tables`一样,但只显示用户表。 |
|
||
| `pg_stat_xact_all_tables` | 和`pg_stat_all_tables`相似,但计数动作只在当前事务内发生(还*没有*被包括在`pg_stat_all_tables`和相关视图中)。用于生存和死亡行数量的列以及清理和分析动作在此视图中不出现。 |
|
||
| `pg_stat_xact_sys_tables` | 和`pg_stat_xact_all_tables`一样,但只显示系统表。 |
|
||
| `pg_stat_xact_user_tables` | 和`pg_stat_xact_all_tables`一样,但只显示用户表。 |
|
||
| `pg_stat_all_indexes` | 当前数据库中的每个索引一行,显示:表OID、索引OID、模式名、表名、索引名、 使用了该索引的索引扫描总数、索引扫描返回的索引记录数、使用该索引的简 单索引扫描抓取的活表(livetable)中数据行数。 当前数据库中的每个索引一行,显示与访问指定索引有关的统计信息。详见[pg_stat_all_indexes](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-ALL-INDEXES-VIEW)。 |
|
||
| `pg_stat_sys_indexes` | 和`pg_stat_all_indexes`一样,但只显示系统表上的索引。 |
|
||
| `pg_stat_user_indexes` | 和`pg_stat_all_indexes`一样,但只显示用户表上的索引。 |
|
||
| `pg_statio_all_tables` | 当前数据库中每个表一行(包括TOAST表),显示:表OID、模式名、表名、 从该表中读取的磁盘块总数、缓冲区命中次数、该表上所有索引的磁盘块读取总数、 该表上所有索引的缓冲区命中总数、在该表的辅助TOAST表(如果存在)上的磁盘块读取总数、 在该表的辅助TOAST表(如果存在)上的缓冲区命中总数、TOAST表的索引的磁盘块读 取总数、TOAST表的索引的缓冲区命中总数。 当前数据库中的每个表一行,显示有关在指定表上 I/O 的统计信息。详见[pg_statio_all_tables](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STATIO-ALL-TABLES-VIEW)。 |
|
||
| `pg_statio_sys_tables` | 和`pg_statio_all_tables`一样,但只显示系统表。 |
|
||
| `pg_statio_user_tables` | 和`pg_statio_all_tables`一样,但只显示用户表。 |
|
||
| `pg_statio_all_indexes` | 当前数据库中每个索引一行,显示:表OID、索引OID、模式名、 表名、索引名、该索引的磁盘块读取总数、该索引的缓冲区命中总数。 当前数据库中的每个索引一行,显示与指定索引上的 I/O 有关的统计信息。详见[pg_statio_all_indexes](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STATIO-ALL-INDEXES-VIEW)。 |
|
||
| `pg_statio_sys_indexes` | 和`pg_statio_all_indexes`一样,但只显示系统表上的索引。 |
|
||
| `pg_statio_user_indexes` | 和`pg_statio_all_indexes`一样,但只显示用户表上的索引。 |
|
||
| `pg_statio_all_sequences` | 当前数据库中每个序列对象一行,显示:序列OID、模式名、序列名、序列的磁盘读取总数、序列的缓冲区命中总数。 当前数据库中的每个序列一行,显示与指定序列上的 I/O 有关的统计信息。详见[pg_statio_all_sequences](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STATIO-ALL-SEQUENCES-VIEW)。 |
|
||
| `pg_statio_sys_sequences` | 和`pg_statio_all_sequences`一样,但只显示系统序列(目前没有定义系统序列,因此这个视图总是为空)。 |
|
||
| `pg_statio_user_sequences` | 和`pg_statio_all_sequences`一样,但只显示用户序列。 |
|
||
| `pg_stat_user_functions` | 对于所有跟踪功能,函数的OID,模式,名称,数量 通话总时间,和自我的时间。自我时间是 在函数本身所花费的时间量,总时间包括 它调用函数所花费的时间。时间值以毫秒为单位。 每一个被跟踪的函数一行,显示与执行该函数有关的统计信息。详见[pg_stat_user_functions](http://www.postgres.cn/docs/9.6/monitoring-stats.html#PG-STAT-USER-FUNCTIONS-VIEW)。 |
|
||
| `pg_stat_xact_user_functions` | 和`pg_stat_user_functions`相似,但是只统计在当前事务期间的调用(还*没有*被包括在`pg_stat_user_functions`中)。 |
|
||
| `pg_stat_progress_vacuum` | 每个运行`VACUUM`的后端(包括自动清理工作者进程)一行,显示当前的进度。见[第 28.4.1 节](http://www.postgres.cn/docs/9.6/progress-reporting.html#VACUUM-PROGRESS-REPORTING)。 |
|
||
|
||
### 常用统计语句
|
||
|
||
```plsql
|
||
-- 按照拉取数据条数降序,查看所有表。
|
||
SELECT * FROM pg_stat_user_tables ORDER BY seq_tup_read DESC;
|
||
|
||
-- 按照函数调用次数降序,查看所有存储过程调用情况
|
||
SELECT * FROM pg_stat_user_functions ORDER BY calls DESC;
|
||
|
||
-- 查看表使用的buffer
|
||
SELECT
|
||
relname,
|
||
count(*) AS buffers
|
||
FROM pg_class c
|
||
JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
|
||
INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
|
||
WHERE c.relname NOT LIKE 'pg%'
|
||
GROUP BY c.relname
|
||
ORDER BY 2 DESC;
|
||
|
||
-- 检查表的脏页
|
||
SELECT
|
||
relname,
|
||
b.isdirty
|
||
FROM pg_class c
|
||
JOIN pg_buffercache b ON b.relfilenode = c.relfilenode
|
||
INNER JOIN pg_database d ON (b.reldatabase = d.oid AND d.datname = current_database())
|
||
WHERE c.relname NOT LIKE 'pg%'
|
||
ORDER BY 2 DESC;
|
||
```
|
||
|