pgstattuple 模块提供了多种用于获取元组级统计信息的函数。
由于这些函数会返回详细的页级信息,因此默认会限制访问。默认情况下,只有 角色 pg_stat_scan_tables 拥有 EXECUTE 权限。超级用户当然可以绕过这一限制。安装该扩展后,用户可以发出 GRANT 命令来更改这些函数上的权限,以允许其他用户 执行它们。不过,更可取的做法可能是将这些用户加入 pg_stat_scan_tables 角色。
pgstattuple(regclass) returns record #pgstattuple 返回一个关系的物理长度、“死” 元组所占百分比以及其他信息。这可以帮助用户判断是否需要执行清理。参数是 目标关系的名称(可选带模式限定)或 OID。例如:
test=> SELECT * FROM pgstattuple('pg_catalog.pg_proc');
-[ RECORD 1 ]------+-------
table_len | 458752
tuple_count | 1470
tuple_len | 438896
tuple_percent | 95.67
dead_tuple_count | 11
dead_tuple_len | 3157
dead_tuple_percent | 0.69
free_space | 8932
free_percent | 1.95
输出列的说明见 Table F.24。
Table F.24. pgstattuple 输出列
| 列 | 类型 | 描述 |
|---|---|---|
table_len |
bigint |
关系的物理长度(字节) |
tuple_count |
bigint |
活元组数量 |
tuple_len |
bigint |
活元组总长度(字节) |
tuple_percent |
float8 |
活元组百分比 |
dead_tuple_count |
bigint |
死元组数量 |
dead_tuple_len |
bigint |
死元组总长度(字节) |
dead_tuple_percent |
float8 |
死元组百分比 |
free_space |
bigint |
总空闲空间(字节) |
free_percent |
float8 |
空闲空间百分比 |
table_len 总会大于 tuple_len、 dead_tuple_len 和 free_space 之和。差值来自固定的页开销、每页的元组指针表,以及为保证元组正确 对齐而产生的填充。
pgstattuple 只会在该关系上获取读锁。因此,结果并不 代表一个瞬时快照;并发更新会影响结果。
如果 HeapTupleSatisfiesDirty 返回 false, pgstattuple 就会将该元组判定为“死”。
pgstattuple(text) returns record #这与 pgstattuple(regclass) 相同,只是目标关系是以 TEXT 指定的。该函数目前保留只是出于向后兼容考虑,并将在未来的某个 版本中弃用。
pgstatindex(regclass) returns record #pgstatindex 返回一条记录,显示有关 B-树索引的信息。 例如:
test=> SELECT * FROM pgstatindex('pg_cast_oid_index');
-[ RECORD 1 ]------+------
version | 2
tree_level | 0
index_size | 16384
root_block_no | 1
internal_pages | 0
leaf_pages | 1
empty_pages | 0
deleted_pages | 0
avg_leaf_density | 54.27
leaf_fragmentation | 0
输出列如下:
| 列 | 类型 | 描述 |
|---|---|---|
version |
integer |
B-树版本号 |
tree_level |
integer |
根页所在的树层级 |
index_size |
bigint |
索引总大小(字节) |
root_block_no |
bigint |
根页的位置(若无则为零) |
internal_pages |
bigint |
“内部”(上层)页的数量 |
leaf_pages |
bigint |
叶子页数量 |
empty_pages |
bigint |
空页数量 |
deleted_pages |
bigint |
已删除页数量 |
avg_leaf_density |
float8 |
叶子页平均密度 |
leaf_fragmentation |
float8 |
叶子页碎片化程度 |
报告的 index_size 通常会比 internal_pages + leaf_pages + empty_pages + deleted_pages 所对应的页数多 1 页,因为它还包含索引的元页。
与 pgstattuple 一样,结果是逐页累积得到的,因此不 应期望它表示整个索引的瞬时快照。
pgstatindex(text) returns record #这与 pgstatindex(regclass) 相同,只是目标索引是以 TEXT 指定的。该函数目前保留只是出于向后兼容考虑,并将在未来的某个 版本中弃用。
pgstatginindex(regclass) returns record #pgstatginindex 返回一条记录,显示有关 GIN 索引的信息。 例如:
test=> SELECT * FROM pgstatginindex('test_gin_index');
-[ RECORD 1 ]--+--
version | 1
pending_pages | 0
pending_tuples | 0
输出列如下:
| 列 | 类型 | 描述 |
|---|---|---|
version |
integer |
GIN 版本号 |
pending_pages |
integer |
待处理列表中的页数 |
pending_tuples |
bigint |
待处理列表中的元组数 |
pgstathashindex(regclass) returns record #pgstathashindex 返回一条记录,显示有关 HASH 索引的 信息。例如:
test=> select * from pgstathashindex('con_hash_index');
-[ RECORD 1 ]--+-----------------
version | 4
bucket_pages | 33081
overflow_pages | 0
bitmap_pages | 1
unused_pages | 32455
live_items | 10204006
dead_items | 0
free_percent | 61.8005949100872
输出列如下:
| 列 | 类型 | 描述 |
|---|---|---|
version |
integer |
HASH 版本号 |
bucket_pages |
bigint |
桶页数量 |
overflow_pages |
bigint |
溢出页数量 |
bitmap_pages |
bigint |
位图页数量 |
unused_pages |
bigint |
未使用页数量 |
live_items |
bigint |
活元组数量 |
dead_tuples |
bigint |
死元组数量 |
free_percent |
float |
空闲空间百分比 |
pg_relpages(regclass) returns bigint #pg_relpages 返回该关系中的页数。
pg_relpages(text) returns bigint #这与 pg_relpages(regclass) 相同,只是目标关系是以 TEXT 指定的。该函数目前保留只是出于向后兼容考虑,并将在未来的某个 版本中弃用。
pgstattuple_approx(regclass) returns record #pgstattuple_approx 是 pgstattuple 的一种更快替代方案,返回近似结果。参数是目标关系的名称或 OID。 例如:
test=> SELECT * FROM pgstattuple_approx('pg_catalog.pg_proc'::regclass);
-[ RECORD 1 ]--------+-------
table_len | 573440
scanned_percent | 2
approx_tuple_count | 2740
approx_tuple_len | 561210
approx_tuple_percent | 97.87
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
approx_free_space | 11996
approx_free_percent | 2.09
输出列的说明见 Table F.25。
pgstattuple 总是执行全表扫描,并返回活元组和死元组 的精确计数及其总长度,以及空闲空间;相比之下, pgstattuple_approx 试图避免全表扫描,返回精确的 死元组统计信息,以及活元组数量、活元组总长度和空闲空间的近似值。
它通过跳过那些根据可见性映射只包含可见元组的页来做到这一点(如果某页 设置了相应的 VM 位,就假定该页不包含死元组)。对于这类页,它从空闲 空间映射中得出空闲空间值,并假定页中其余空间都被活元组占用。
对于不能跳过的页,它会扫描每个元组,在相应的计数器中记录其存在和 大小,并累加该页上的空闲空间。最后,它根据扫描过的页数和元组数来估算 活元组总数(方法与 VACUUM 估算 pg_class.reltuples 时相同)。
Table F.25. pgstattuple_approx 输出列
| 列 | 类型 | 描述 |
|---|---|---|
table_len |
bigint |
关系的物理长度(字节,精确) |
scanned_percent |
float8 |
已扫描表的百分比 |
approx_tuple_count |
bigint |
活元组数量(估计) |
approx_tuple_len |
bigint |
活元组总长度(字节,估计) |
approx_tuple_percent |
float8 |
活元组百分比 |
dead_tuple_count |
bigint |
死元组数量(精确) |
dead_tuple_len |
bigint |
死元组总长度(字节,精确) |
dead_tuple_percent |
float8 |
死元组百分比 |
approx_free_space |
bigint |
总空闲空间(字节,估计) |
approx_free_percent |
float8 |
空闲空间百分比 |
在上述输出中,空闲空间数值可能与 pgstattuple 的 输出不完全一致,因为空闲空间映射给出的数值是确定的,但不保证精确到 字节。
Tatsuo Ishii、Satoshi Nagayasu 和 Abhijit Menon-Sen
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。