
前言
今天我们来聊聊PostgreSQL中的truncate后文件有什么变化?本文暂时不做特别深入的研究,只是简单地观察数据库视图及文件等信息。
Truncate之后文件发生了哪些变化
从创建一个表开始,首先模拟插入一些数据。
postgres=# create table t1 (id numeric,name text);
CREATE TABLE
postgres=#
postgres=# insert into t1 select generate_series(1,10000000),md5(random()::text);
INSERT 0 10000000
postgres=#
postgres=# \d t1
Table "public.t1"
Column | Type | Collation | Nullable | Default
--------+---------+-----------+----------+---------
id | numeric | | |
name | text | | |
在创建完表后,将作为独立文件存储,并使用relfilenode编号。通过查询relfilenode号,我们发现有三个文件,分别是表的数据文件、表的空闲空间映射文件(fsm)、表的可见映射文件(vm)。
postgres=# checkpoint;
CHECKPOINT
postgres=# SELECT relfilenode FROM pg_class WHERE relname='t1';
relfilenode
-------------
41064
(1 row)
postgres=# select pg_relation_filepath('t1');
pg_relation_filepath
----------------------
base/12711/41064
[postgres@centos8 12711]$ ls -lrt 41064*
-rw-------. 1 postgres postgres 188416 Feb 25 13:06 41064_fsm
-rw-------. 1 postgres postgres 24576 Feb 25 13:07 41064_vm
-rw-------. 1 postgres postgres 682672128 Feb 25 13:09 41064
现在在我们发起 truncate命令之后,我们看看发生了什么。
postgres=# truncate table t1;
TRUNCATE TABLE
[postgres@centos8 12711]$ ls -lrt 41064*
-rw-------. 1 postgres postgres 0 Feb 25 13:10 41064
可见数据文件被完全清空,大小为0,而空闲空间映射文件(fsm)和表可见性映射文件(vm)被删除。与此同时, PostgreSQL它还会修改relfilenode。
postgres=# SELECT relfilenode FROM pg_class WHERE relname='t1';
relfilenode
-------------
41071
(1 row)
postgres=# select pg_relation_filepath('t1');
pg_relation_filepath
----------------------
base/12711/41071
(1 row)
此时该表的relfilenode已经变成了41071。
[postgres@centos8 12711]$ ls -lrt 41071*
-rw-------. 1 postgres postgres 0 Feb 25 13:10 41071
若此时执行一次checkpoint,则将彻底清除先前的41064文件。
尾声
THE END
不难看出当发生truncate之后,和oracle不一样。PostgreSQL将直接把文件清空。而Oracle在truncate之后只是修改一个标识位,数据还保留着,只是过段时间会覆盖而已,此时Oracle的数据我们还能进行恢复。而PostgreSQL的恢复就比较困难了。但是也不是没有办法。需要使用底层文件系统工具进行扫描,恢复出被删除的文件,然后再用之前我们介绍过的pg_dumpfile进行恢复。当然如果你有备份,也可以直接使用备份来恢复。
文章转载自励志成为PostgreSQL大神,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




