一、为什么需要VACUUM FULL
常规vacuuming可以释放比页面修剪更多的空间,但有时可能仍然不够。
如果表或索引文件的大小增加了,vacuum可以清理页中的一些空间,但很少能减少页的数量。只有在文件末尾出现几个空页的情况下,回收的空间才能返回给操作系统,这种情况概率很小。
过大的尺寸可能会导致:
• 全表(或索引)扫描将花费更长的时间。
• 可能需要更大的缓存(页作为一个整体缓存,因此数据密度降低)。
• B-trees 可以增加一层,这会降低索引访问的速度。
• 文件占用磁盘和备份的额外空间。
如果文件中有用数据的比例降到了某个合理的水平以下,管理员可以通过运行vacuum full命令执行完全清理。在这种情况下,表及其所有索引都是从头开始重建的,并且数据被尽可能压实。
当执行完全清理时,PostgreSQL首先完全重建表,然后重建其每个索引。在重建对象时,新旧文件都必须存储在磁盘上,因此这个过程可能需要大量的空闲空间。
而且,该操作完全阻塞了对表的访问,包括读和写。
二、表的VACUUM FULL实验
创建测试数据
test1=# drop table test1;
test1=# create table test1(id int,name varchar(10));
test1=# create index idx_id on test1(id);
test1=# insert into test1 values(generate_series(1,100000),'aaa');
创建pgstattuple扩展,可以观测表和索引的数据密度
test1=# create extension pgstattuple;
查看表和索引的数据密度
#查看表的数据密度
test1=# select * from pgstattuple('test1') \gx
-[ RECORD 1 ]------+--------
table_len | 3629056
tuple_count | 100000
tuple_len | 3200000
tuple_percent | 88.18
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 16652
free_percent | 0.46
#该函数读取整个表,并在其文件中显示有关空间分布的统计信息。tuple_percent字段显示已用数据(堆元组)占用的空间百分比。由于页中存在各种元数据,这个值肯定小于100%,但在本例中,这个值仍然很高