【问题标题】:How to shrink pg_toast table?如何缩小 pg_toast 表?
【发布时间】:2019-04-15 00:53:32
【问题描述】:

我在 mac osx 上的 postgres 9.3 上运行,我有一个失控的数据库。我曾经有一个表,其中有一列存储大量数据。然后我注意到,仅仅因为 pg_toast 表,db 的大小就增长到了 19gb 左右。然后我删除了提到的列并运行了真空,以使数据库再次变小,但它保持不变。那么如何缩小数据库大小呢?

 SELECT nspname || '.' || relname AS "relation"
       ,pg_size_pretty(pg_relation_size(C.oid)) AS "size" 
 FROM pg_class C 
     LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace) 
 WHERE nspname NOT IN ('pg_catalog', 'information_schema') 
 ORDER BY pg_relation_size(C.oid) DESC 
 LIMIT 20;

结果

 pg_toast.pg_toast_700305                    | 18 GB
 pg_toast.pg_toast_700305_index              | 206 MB
 public.catalog_hotelde_images               | 122 MB
 public.routes                               | 120 MB



    VACUUM VERBOSE ANALYZE pg_toast.pg_toast_700305;                                                                                                                                            INFO:  vacuuming "pg_toast.pg_toast_700305"
INFO:  index "pg_toast_700305_index" now contains 9601330 row versions in 26329 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU 0.06s/0.02u sec elapsed 0.33 sec.
INFO:  "pg_toast_700305": found 0 removable, 0 nonremovable row versions in 0 out of 2393157 pages
DETAIL:  0 dead row versions cannot be removed yet.
There were 0 unused item pointers.
0 pages are entirely empty.
CPU 0.06s/0.07u sec elapsed 0.37 sec.
VACUUM

路由表的结构

id serial NOT NULL,
  origin_id integer,
  destination_id integer,
  total_time integer,
  total_distance integer,
  speed_id integer,
  uid bigint,
  created_at timestamp without time zone,
  updated_at timestamp without time zone,
  CONSTRAINT routes_pkey PRIMARY KEY (id)

【问题讨论】:

  • toast 表存储任何“大”列的数据。任何实际值超过某个阈值的可变长度数据类型都将存储在那里。您可能还有其他列会影响该表的大小
  • 正是我读到的关于 toast 表的内容,我删除了包含大数据的列,只包含非常小的值。我把路由表的结构贴在原帖里,你可以看到。
  • 你怎么知道那些toast表属于routes表?

标签: postgresql


【解决方案1】:

尝试以下方法:

vacuum full

【讨论】:

  • 就是这样!桌子被清理干净了。谢谢
  • 危险,威尔罗宾逊,危险!在生产系统上运行 VACUUM FULL 之前,请确保您知道 potential consequences
  • 尝试构建一个新表并与旧表交换以减少对生产的影响。
  • @hakamadare "本文档对于 PostgreSQL 9.0 及更高版本已过时。大部分内容仅适用于 PostgreSQL 8.4 及更低版本。"
  • @BenjaminToueg Vacuum 完整作品或“vacuum full table_name”也可以。正如 linuxfreaks 所提到的,重建表,删除旧表并将重建的表重命名为原始名称也可以。没有什么太花哨的,vacuum full 命令基本上是“锁定”表,然后对其进行“碎片整理”(简化)。重建是“刷新所有数据”,速度更快,但它在生产系统上也存在问题,因为您的旧表数据可能会在此过程中被修改。如果系统关闭,任何一种方式都可以正常工作。
【解决方案2】:

您可以使用以下两种吸尘方式之一:standardfull

标准:

VACUUM table_name;

满:

VACUUM FULL table_name; 

请记住,VACUUM FULL 会锁定它正在处理的表,直到它完成为止。

您可能希望在频繁上传/删除活动的表上更频繁地执行标准清理,它可能不会像清理完全一样为您提供足够的空间,但您将能够运行诸如 SELECT、INSERT、UPDATE 和DELETE,它将花费更少的时间来完成。

在我的例子中,当 pg_toast(连同其他表)失控时,标准 VACUUM 会产生细微的差别,但还不够。我使用 VACUUM FULL 来回收更多的磁盘空间,这在大型关系上非常慢。我决定tune autovacuum 并在我经常更新的表上更频繁地使用标准 VACUUM。

如果您需要使用 VACUUM FULL,则应在用户不太活跃时使用。 另外,不要关闭 autovacuum。

您可以通过在命令中添加 verbose 来获得一些额外的信息:

VACUUM FULL VERBOSE table_name;

【讨论】:

    猜你喜欢
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多