AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 112637
Accepted
Spike
Spike
Asked: 2015-08-30 12:53:53 +0800 CST2015-08-30 12:53:53 +0800 CST 2015-08-30 12:53:53 +0800 CST

我可以对 pg_largeobject 表执行 VACUUM FULL 吗?

  • 772

我在 Postgres 9.1 数据库中有两个表 ( table1, )。table2两者都有oid类型。每张表100万条记录。pg_largeobject表大小约为 40GB 。我从每个表中删除了 90 万条记录,并执行了以下命令。

vacuum full analyze table1;
vacuum full analyze table2;

表大小仍然没有变化pg_largeobject(启用自动真空)

我是否也需要执行上述命令到pg_largeobject表格?它会影响什么吗?

postgresql postgresql-9.1
  • 1 1 个回答
  • 16212 Views

1 个回答

  • Voted
  1. Best Answer
    Erwin Brandstetter
    2015-08-30T15:36:33+08:002015-08-30T15:36:33+08:00

    你可以运行它,没问题:

    VACUUM FULL ANALYZE pg_largeobject;
    

    甚至可能删除一些死行。细节:

    • VACUUM 将磁盘空间返回给操作系统

    但这可能不会解决您的实际问题。

    当使用Postgres的大对象工具时,大对象(“blob”:二进制大对象)本身被分解成存储在系统表中的二进制数据块pg_largeobject。PK 由两列组成,(loid, pageno)用于引用用户表中的 blob。OID可以多次引用同一个 blob 。loidoid

    删除用户表中的行不会删除 blob。一方面,同一个 blob 可能被多次引用。您有责任自己跟踪并实际删除“未链接”的 blob。一种方法是使用lo_unlink():

    SELECT lo_unlink(173454);  -- deletes large object with OID 173454
    

    由于您已经使用引用删除了行,因此oid您需要更有创意来识别未链接的 blob。假设您没有从任何其他地方引用 blob,您可以使用此查询来修复:

    SELECT lo_unlink(l.loid)
    FROM   pg_largeobject l
    GROUP  BY loid
    HAVING (NOT EXISTS (SELECT 1 FROM table1 t WHERE t.oid = l.loid))
    AND    (NOT EXISTS (SELECT 1 FROM table2 t WHERE t.oid = l.loid));
    

    您需要成为超级用户才能直接访问pg_largeobject。table1假设和中的列名table2是oid。基于pg_largeobject_metadataPostgres 9.3 或更高版本的更简单查询(如@Daniel 评论):

    SELECT lo_unlink(l.oid)
    FROM   pg_largeobject_metadata l
    WHERE (NOT EXISTS (SELECT 1 FROM table1 WHERE t.oid = l.oid))
    AND   (NOT EXISTS (SELECT 1 FROM table2 WHERE t.oid = l.oid));
    

    pg_largeobject_metadata是公开可读的。但是我在 pg 9.3 之前的版本(包括 pg 9.1)中没有看到系统表中 blob 的 OID - 至少在手册中没有,我现在没有旧版本要测试。所以你可能必须使用我的第一个查询。

    前后对比:

    SELECT count(*) FROM pg_largeobject;
    SELECT pg_size_pretty(pg_table_size('pg_largeobject'));
    

    您VACUUM FULL现在可以运行,然后再次测试:

    VACUUM FULL ANALYZE pg_largeobject;
    

    您将对Postgres 9.1 可用的附加模块感兴趣。lo该手册对您的问题有准确的描述:

    ...一个表条目可以通过 OID 引用一个大对象,但是可以有多个表条目引用同一个大对象 OID,因此系统不会因为您更改或删除一个这样的条目而删除大对象。

    大胆强调我的。该模块也提供了一个解决方案:

    该lo模块允许通过将触发器附加到包含 LO 引用列的表来解决此问题。触发器基本上只是 lo_unlink在您删除或修改引用大对象的值时执行。

    对于每个 blob在整个数据库中仅引用一次的用例。


    显然也(就像@Daniel提到的那样)vacuumlo:

    vacuumlo 是一个简单的实用程序,它将从 PostgreSQL 数据库中删除任何“孤立的”大对象。

    • 17

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve