了解 pg_toast 的来源

leo*_*sas 3 postgresql postgresql-9.6

我在 pg_toast 中有相当多的存储空间

             relation             |  size
----------------------------------+---------
 pg_toast.pg_toast_43934449       | 87 GB
 pg_toast.pg_toast_43934438       | 64 GB
 pg_toast.pg_toast_50877          | 35 GB
 pg_toast.pg_toast_16715          | 15 GB
 pg_toast.pg_toast_16813          | 13 GB
 pg_toast.pg_toast_5706469        | 1335 MB
 pg_toast.pg_toast_43934449_index | 1004 MB
 pg_toast.pg_toast_43934438_index | 942 MB
 pg_toast.pg_toast_16715_index    | 709 MB
 pg_toast.pg_toast_16813_index    | 548 MB
 pg_toast.pg_toast_50877_index    | 530 MB
 pg_toast.pg_toast_3518414        | 463 MB
 pg_toast.pg_toast_16994          | 339 MB
 pg_toast.pg_toast_46608          | 310 MB
 pg_toast.pg_toast_16994_index    | 92 MB
 pg_toast.pg_toast_22345124       | 68 MB
 pg_toast.pg_toast_46608_index    | 51 MB
 pg_toast.pg_toast_437018         | 43 MB
 pg_toast.pg_toast_5706469_index  | 15 MB
 pg_toast.pg_toast_3518414_index  | 13 MB
(20 rows)
Run Code Online (Sandbox Code Playgroud)

当数据库的总大小目前约为 420GB 时,这很重要。这是完全可以预料的,因为我的一些表将 JSON 存储为任何一种text类型(对于我的一些旧表)或jsonb一些新表。

只需删除一些较旧的数据,就可以在应用程序级别清理这些列中的许多列。问题是很难知道 pg_toast 表的实际贡献是什么?

如何将 pg_toast 反向跟踪到另一个表的实际行/列引用?

Lau*_*lbe 8

您可以使用此查询找出所有带有 TOAST 表的表:

SELECT oid::regclass,
       reltoastrelid::regclass,
       pg_relation_size(reltoastrelid) AS toast_size
FROM pg_class
WHERE relkind = 'r'
  AND reltoastrelid <> 0
ORDER BY 3 DESC;
Run Code Online (Sandbox Code Playgroud)

要找出表中哪些列占用的空间最多,您可以尝试这样的查询

SELECT sum(length(col1)) AS col1_size,
       sum(length(col2)) AS col2_site
FROM some_table;
Run Code Online (Sandbox Code Playgroud)

这里col1col2textvarcharchar或者bytea列,这通常是最大的。使用其他数据类型,jsonb您可以将其转换为text以获得估计值。


Phi*_* W. 6

在内部,postgres 通过 oid 识别几乎所有内容 - TOAST 表名称的数字部分应该是表的标识符:

来自PostgreSQL.org

... toast 表名称的数字部分是其父表的 OID,所以实际上你只需要这样做

选择 '43934449'::regclass ;

不过,确认 reltoastrelid 链接是个好主意。