Postgresql之磁盘消耗查询
Author:OnceDay Date:2023年3月15日
漫漫长路,才刚刚开始…
1.推荐参看文档
1.1 手动查询数据库大小
首先使用\l
查看当前postgresql中有哪些数据库(测试用例中有三个数据库):
postgres=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
----------------+-------------+-----------+---------+-------+-----------------------
test_Database | onced_day1 | UTF8 | C | C |
temp_database | onced_day2 | SQL_ASCII | C | C |
postgres | postgres | SQL_ASCII | C | C |
(3 rows)
然后通过命令获取到数据库对应的OID,如下:
postgres=# SELECT oid from pg_database where datname='test_Database';
oid
--------
537426
(1 row)
然后从pgsql的data/base/<oid>
文件夹获取对应的大小,如下:
onceday->data:# du -sh base/537426/
290M base/537426/
手动命令需要去获取数据库对应的OID来查询。
2. 命令函数查询
下面是常见的postgresql数据库对象尺寸查询函数:
函数名 | 返回类型 | 描述 |
---|---|---|
pg_column_size(any) | int | 存储一个指定的数值需要的字节数(可能压缩过) |
pg_database_size(oid) | bigint | 指定OID的数据库使用的磁盘空间 |
pg_database_size(name) | bigint | 指定名称的数据库使用的磁盘空间 |
pg_indexes_size(regclass) | bigint | 关联指定表OID或表名的表索引的使用总磁盘空间 |
pg_relation_size(relation regclass,fork text) | bigint | 指定OID或名的表或索引,通过指定fork(‘main’,‘fsm’ 或’vm’)所使用的磁盘空间 |
pg_relation_size(relation regclass) | bigint | pg_relation_size(...,'main')的缩写 |
pg_size_pretty(bigint) | text | Converts a size in bytes expressed as a 64-bit integer into a human-readable format with size units |
pg_size_pretty(numeric) | text | 把以字节计算的数值转换成一个人类易读的尺寸单位 |
pg_table_size(regclass) | bigint | 指定表OID或表名的表使用的磁盘空间,除去索引(但是包含TOAST,自由空间映射和可视映射) |
pg_tablespace_size(oid) | bigint | 指定OID的表空间使用的磁盘空间 |
pg_tablespace_size(name) | bigint | 指定名称的表空间使用的磁盘空间 |
pg_total_relation_size(regclass) | bigint | 指定表OID或表名使用的总磁盘空间,包括所有索引和TOAST数据 |
2.1 查询一个指定的数值需要的字节数
这个是用来查询一个固定对象类型所需要的字节数,如下面查询整数和字符串所占用的字节数。
正常的小整数,只需要四个字节:
postgres=# select pg_column_size(1024);
pg_column_size
----------------
4
(1 row)
超大的整数,就需要8个字节了:
postgres=# select pg_column_size(102400000000);
pg_column_size
----------------
8
(1 row)
对于字符串来说,其字节数和字符串长度有关。
postgres=# select pg_column_size('hello world!');
pg_column_size
----------------
13
(1 row)
对于可变类型来说,其字节数和具体值有关:
postgres=# select pg_column_size('inet::192.168.1.1');
pg_column_size
----------------
18
(1 row)
postgres=# select pg_column_size('inet::2001::1002');
pg_column_size
----------------
17
(1 row)
2.1 查看数据库大小
使用pg_database_size
命令即可查看指定数据库的大小,这里输入的名字需要用单引号括起来,且支持大小写。
temp_database=# select pg_database_size('temp_database');
pg_database_size
------------------
7868975
(1 row)
这里输出的数据单位是字节数,不太适合阅读,但适合于精确的数据库大小,可以使用pg_size_pretty
转为合适阅读的单位。
temp_database=# select pg_size_pretty(pg_database_size('temp_database')) as size;
size
---------
7685 kB
(1 row)
可以直接使用pg_database_size('test_Database')
去查询test_database
这种含有大写字母的数据库名字。
如下所示:
temp_database=# select pg_size_pretty(pg_database_size('test_Database')) as size;
size
--------
288 MB
(1 row)
使用下面命令可以查看所有数据库大小:
select datname,pg_size_pretty(pg_database_size(datname)) AS size from pg_database;
为了更好展示数据,可以使用下面这个脚本:
使用方式:
- 先创建一个
query.sql
文件,将脚本命令写进去。 - 然后在
postgres
账户下执行psql -f ./query.sql
命令即可。
下面是脚本内容:
SELECT d.datname AS Name,pg_catalog.pg_get_userbyid(d.datdba) AS Owner,CASE WHEN pg_catalog.has_database_privilege(d.datname,'CONNECT')
THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))
ELSE 'No Access'
END AS SIZE
FROM pg_catalog.pg_database d
ORDER BY
CASE WHEN pg_catalog.has_database_privilege(d.datname,'CONNECT')
THEN pg_catalog.pg_database_size(d.datname)
ELSE NULL
END DESC -- nulls first
LIMIT 20
2.2 查看数据库的表大小
首先可以使用pg_relation_size()
来获取索引的大小,在数据库里,索引大小占用的比例可不低。
首先使用\d tablename
输出表格的详细信息,如下:
test_Database=# \d "test_Database_table"
Table "public.test_Database_table"
Column | Type | Collation | Nullable | Default
------------+------------------+-----------+----------+---------
timestamp | bigint | | |
type | integer | | |
Indexes:
"test_Database_table_timestamp_index" btree ("timestamp")
"test_Database_table_type_index" btree (type)
使用test_Database_table_timestamp_index
等索引名来获取对应索引的大小:
test_Database=# select pg_size_pretty(pg_relation_size('"test_Database_table_timestamp_index"')) as size;
size
--------
856 kB
(1 row)
logConnectDb=# select pg_size_pretty(pg_relation_size('"test_Database_table_type_index"')) as size;
size
--------
304 kB
(1 row)
注意这个单引号里套的双引号,如果不这么做,由于大小写无法识别,将导致报错。
有两种方式获取表的大小(不含索引):pg_relation_size
和pg_table_size
,如下所示:
test_Database=# select pg_size_pretty(pg_relation_size('"test_Database_table"')) as size;
size
---------
2152 kB
(1 row)
test_Database=# select pg_size_pretty(pg_table_size('"test_Database_table"')) as size;
size
---------
2184 kB
(1 row)
可以看到,两者大小基本一致,但table_size更多,因为包含了一些其他的内容在里面。
可以使用pg_total_relation_size
查看一张表数据+索引+其他数据的全部磁盘占用:
test_Database=# select pg_size_pretty(pg_total_relation_size('"test_Database_table"')) as size;
size
---------
3344 kB
(1 row)
可以看到,两个索引大小856KB + 304KB = 1160KB
,然后加上表的pg_relation_size
(纯数据)2152Kb
,即
1160KB + 2152KB = 3312KB = 3344KB - 32KB = 3344Kb - (2184Kb - 2152Kb)
。
很明显,tablesize包含一些额外的其他数据,如TOAST
等。
可以使用下面命令一次查询当前数据库里面多个表的占用大小:
-
不包含索引的表大小,使用
pg_relation_size
函数:select relname,pg_size_pretty(pg_relation_size(relid)) as size from pg_stat_user_tables;
-
不包含索引的表大小,使用
pg_table_size
函数:select relname,pg_size_pretty(pg_table_size(relid)) as size from pg_stat_user_tables;
-
包含索引的整表大小,使用
pg_total_relation_size
函数:select relname,pg_size_pretty(pg_total_relation_size(relid)) as size from pg_stat_user_tables;
也可以使用下面这段脚本代码来获取排序后的输出,如下
使用方法:
- 先创建一个
query.sql
文件,将脚本命令写进去。 - 然后在
postgres
账户下执行psql -d test_Database -f ./query.sql
命令即可。
下面是脚本内容:
SELECT
table_schema || '.' || table_name AS table_full_name,pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size
FROM information_schema.tables
ORDER BY
pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC
原文地址:https://blog.csdn.net/Once_day/article/details/129700617
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。