【PostgreSQL】PG_DUMP的文件大小元小于库占用物理空间统计

PG_DUMP的文件大小元小于库占用物理空间统计

现象描述

使用pg_dump做pg库备份的时候,发现导出的数据量大小远小于统计出来的占用空间大小:

spark_db=# select pg_size_pretty(pg_database_size('spark_db'));      
 pg_size_pretty 
----------------
 19 GB
(1 row)

接下来是pg_dump出来的数据量大小:

[postgres@gsqzj11184 ~]$ pg_dump -h127.0.0.1 -p5832 -Upostgres spark_db -f /tmp/spark.sql
Password: 
[postgres@gsqzj11184 ~]$ du -sh /tmp/spark.sql 
626M    /tmp/spark.sql

问题复现

创建一个测试库dump_test:

create database dump_test;
/ ======================================
postgres=# \l
                                  List of databases
    Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
------------+----------+----------+-------------+-------------+-----------------------
 dump_test  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 postgres   | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 promanager | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres         +
            |          |          |             |             | postgres=CTc/postgres+
            |          |          |             |             | prom=CTc/postgres
 template0  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |          |          |             |             | postgres=CTc/postgres
 template1  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
            |          |          |             |             | postgres=CTc/postgres

创建测试表t1并插入测试数据:

postgres=# \c dump_test 
You are now connected to database "dump_test" as user "postgres".
dump_test=# create table t1(id int);
CREATE TABLE
dump_test=# insert into t1 select generate_series(1,400000000);
INSERT 0 400000000
dump_test=# 

查看数据库物理空间大小,此时是14个G:

dump_test=# select pg_size_pretty(pg_database_size('dump_test'));
 pg_size_pretty 
----------------
 14 GB
(1 row)

接下来模拟日常对数据库进行频繁删除的情况,这里直接删除大量数据,大小并没有发生变化:

dump_test=# delete from t1 where id <> 40000000;
DELETE 399999999
dump_test=# select pg_size_pretty(pg_database_size('dump_test'));
 pg_size_pretty 
----------------
 14 GB
(1 row)

此时表中也只有1条数据:

dump_test=# select count(1) from t1;
 count 
-------
     1
(1 row)

此时使用pg_dump备份数据,查看大小,只有4.0K:

[root@vmax67029 ~]# pg_dump -h127.0.0.1 -p5832 -Upostgres dump_test -f /tmp/dump_test.sql
Password: 
[root@vmax67029 ~]# du -sh /tmp/dump_test.sql 
4.0K    /tmp/dump_test.sql

查看t1表的大小,是不是没有变化:

dump_test=# 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 
 where table_name ='t1'
ORDER BY
pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC;
 table_schema | table_full_name | size  
--------------+-----------------+-------
 public       | t1              | 14 GB
(1 row)

也就是说,数据虽然删除了,但是统计出来的大小依旧存在,这就是因为触发了高水位,简单来说就是插入1-1000的数据,删除了1-999,这部分空间不会马上释放。

接下来手动做表收缩:

dump_test=# vacuum full t1;
VACUUM
dump_test=# 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 
 where table_name ='t1'
ORDER BY
pg_total_relation_size('"' || table_schema || '"."' || table_name || '"') DESC;
 table_schema | table_full_name |    size    
--------------+-----------------+------------
 public       | t1              | 8192 bytes
(1 row)

再次查看表的大小,只有8192 bytes大小了,而在备份出来的sql文件中,也是只有一条和库内一样的数据:

COPY public.t1 (id) FROM stdin;
40000000
\.

结论

pg_dump备份的数据不会考虑高水位,因此远小于pg内查出来的空间大小是正常的,并不会造成数据丢失。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Meepoljd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值