pgstattuple 模块提供了各种用于获取元组级统计信息的函数。
由于这些函数返回详细的页面级信息,默认情况下访问受到限制。默认情况下,只有 pg_stat_scan_tables 角色拥有 EXECUTE 权限。超级用户当然可以绕过此限制。扩展安装后,用户可以发出 GRANT 命令来更改函数上的权限,允许其他人执行它们。但是,将这些用户添加到 pg_stat_scan_tables 角色可能更可取。
pgstattuple(regclass) returns recordpgstattuple 返回关系(表)的物理长度、“死元组” 的百分比以及其他信息。这可能有助于用户确定是否需要 vacuum。参数是目标关系的名称(可选模式限定)或 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
输出列的描述请参见 表 F.24。
表 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 recordpgstatindex 返回一个记录,显示有关 B-tree 索引的信息。例如
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 版本号 |
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 所占的页面数多一个,因为它还包括索引的元数据页。
与 pgstattuple 一样,结果是逐页累积的,不应期望它们代表整个索引的瞬时快照。
pgstatindex(text) returns record这与 pgstatindex(regclass) 相同,只是目标索引指定为 TEXT。此函数因向后兼容而保留,将在将来的某个版本中弃用。
pgstatginindex(regclass) returns recordpgstatginindex 返回一个记录,显示有关 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 recordpgstathashindex 返回一个记录,显示有关 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 bigintpg_relpages 返回关系中的页面数量。
pg_relpages(text) returns bigint这与 pg_relpages(regclass) 相同,只是目标关系指定为 TEXT。此函数因向后兼容而保留,将在将来的某个版本中弃用。
pgstattuple_approx(regclass) returns recordpgstattuple_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
输出列的描述请参见 表 F.25。
而 pgstattuple 始终执行全表扫描并返回活动元组和死元组(及其大小)以及空闲空间的精确计数,pgstattuple_approx 则尝试避免全表扫描,并返回精确的死元组统计信息以及对活动元组数量和大小以及空闲空间的估计。
它通过跳过那些只有可见元组的页面来实现(根据可见性图)。如果一个页面有相应的 VM 位集,则假定它不包含死元组。对于这样的页面,它从空闲空间映射中派生出空闲空间值,并假定页面上的其余空间被活动元组占用。
对于无法跳过的页面,它会扫描每个元组,记录其存在和大小到相应的计数器中,并累加页面上的空闲空间。最后,它根据扫描的页面和元组数量估计活动元组的总数(与 VACUUM 估计 pg_class.reltuples 的方式相同)。
表 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 and Abhijit Menon-Sen