默认情况下,pg中heap table末端的垃圾page可以被从磁盘中回收空间。
例如当表的末尾的100个数据块里面全是垃圾,那么这100个数据块可以truncate阶段,文件也会变小(不是末尾的垃圾page空间不能被回收)。
pg12开始,pg支持对于末端的垃圾page的回收进行控制,通过表的vacuum_truncate参数设置为false来指定末端page不被回收。
例如一些表还会往里面写入大量数据时,没有必要回收,因为extend block也是有锁的。另外收缩文件需要对表加access exclusive lock,所以如果你不期望有这个锁冲突,同时这个表又还会有新的数据写入(这些空间可以被新写入的数据填满)时,可以将vacuum_truncate设置为false。
例子:
1、创建两张表,表t3的vacuum_truncate设置为false,表t4使用默认参数。
bill=# create table t3(id int,info text) with(vacuum_truncate=false);
CREATE TABLE
bill=# create table t4(id int,info text);
CREATE TABLE
2、插入数据,查看表大小
bill=# insert into t3 select generate_series(1,1000000),md5(random()::text);
INSERT 0 1000000
bill=# insert into t4 select generate_series(1,1000000),md5(random()::text);
INSERT 0 1000000
bill=# \dt+ t3
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------+-------+-------+-------+-------------
bill | t3 | table | bill | 65 MB |
(1 row)
bill=# \dt+ t4
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------+-------+-------+-------+-------------
bill | t4 | table | bill | 65 MB |
(1 row)
3、删除末端数据,观察表大小是否变化
可以看到t4表末端的空间被回收了,而t3表大小仍然不变。
bill=# delete from t4 where id <> 1;
DELETE 999999
bill=# vacuum t4;
VACUUM
bill=# \dt+ t4
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------+-------+-------+-------+-------------
bill | t4 | table | bill | 48 kB |
(1 row)
bill=# delete from t3 where id <> 1;
DELETE 999999
bill=# vacuum t3;
VACUUM
bill=# \dt+ t3
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------+-------+-------+-------+-------------
bill | t3 | table | bill | 65 MB |
(1 row)