PostgreSQL - 恢复的数据库比原始数据库小

时间:2015-03-24 15:02:39

标签: postgresql

我已经使用pg_dump备份了我的PostgreSQL数据库,并且#34; .sql"文件。 当我恢复数据库时,其大小为2.8GB,而源(原始)数据库为3.7GB。访问数据库的应用程序似乎工作正常。

恢复数据库规模较小的原因是什么?

2 个答案:

答案 0 :(得分:7)

简短的回答是数据库存储的速度比空间更优化。

例如,如果您在表中插入了100行,然后删除了每个具有奇数编号ID的行,则DBMS可以写出一个只有50行的新表,但它更简单地标记已删除的行作为可用空间并在下次插入行时重用它们。因此,该表占用的空间是目前所需的两倍。

Postgres使用“MVCC”而不是锁定事务管理使得这更有可能,因为UPDATE通常涉及将新行写入存储,然后在没有事务查看时将旧行标记为删除。 / p>

通过转储和恢复数据库,您将重新创建没有所有可用空间的数据库。这基本上是VACUUM FULL命令的作用 - 它将当前数据重写为新文件,然后删除旧文件。

有一个extension distributed with Postgres called pg_freespace可供您查看其中一些内容。例如您可以列出主表大小(不包括存储在单独的“TOAST”表中的索引和列)以及每个表使用的可用空间,如下所示:

Select oid::regclass::varchar as table,
      pg_size_pretty(pg_relation_size(oid)/1024 * 1024) As size,
      pg_size_pretty(sum(free)) As free
 From (
   Select c.oid,
       (pg_freespace(c.oid)).avail As free
     From pg_class c
     Join pg_namespace n on n.oid = c.relnamespace
    Where c.relkind = 'r'
      And n.nspname Not In ('information_schema', 'pg_catalog')
 ) tbl
 Group By oid
 Order By pg_relation_size(oid) Desc, sum(free) Desc;

答案 1 :(得分:1)

原因很简单:在正常操作期间,当行更新时,PostgreSQL会添加该行的新副本,并将该行的旧副本标记为已删除。这是多版本并发控制(MVCC)的实际应用。然后VACUUM回收旧行占用的空间,用于将来可以插入的数据,但不会将此空间返回到操作系统,因为它位于文件的中间。请注意,VACUUM只有在表中修改了足够的数据或从表中删除后才会立即执行。

你所看到的是完全正常的。它只是表明PostgreSQL数据库的大小将大于行大小的总和。当你开始积极使用它时,你的新数据库很可能会迅速增长到3.7GB。