这个问题的起因在PostgreSQL 测试的过程中,测试人员发现在对POSTGRESQL 产生toast表后,在删除数据,做vacuum full 后发现系统中给出的toast的文件的物理文件名,与文件系统中并不存在,测试人员问到底这个文件去哪了?
首先我们先生成需要测试的表,
select relname, relowner, relfilenode from pg_class where relname = 'toast_t';
通过语句找到表的文件的node id , 文件目录中也有相关的文件
select relname from pg_class where oid = (select reltoastrelid from pg_class where relname='toast_t');
在通过语句我们找到表的 toast文件的文件名
通过toast 的文件名,将实际的物理的toast文件找到,这里需要通过oid2name命令 ,在PG的安装目录或系统变量指定的执行文件的目录,都有这个执行的文件. 通过oid2name -d postgres -t pg_toast_70990 命令,我们找到实际的TOAST 文件的物理名字叫 70993
根据测试的要求,直接删除数据,并且对表进行vacuum full 的操作. 操作完毕toast的表名并未被修改. 但此时toast 文件 70993 在数据库目录中无法被找到了
实际上toast 文件已经被删除,并产生了新的文件76999, 同时文件的大小为0 , 相关的数据空间碎片整理以及空间释放需要验证的问题已经完成.
测试人员产生疑问的主因是,此时在数据库中通过查询语句查询表的TOAST文件的物理文件名还是70933 ,而不是76999,这是测试人员迷惑和误解的地方.
在POSTGRESQL 中数据表和文件是一对多进行使用的, 在PG中数据表文件除数据文件, FRM 文件, VM文件等,还有一种文件叫toast , toast存储POSTGRESQL 中数据字段超过2kb的数据(超过多大可以手动条件,默认为2KB), 通过4中方式处理(这里不再赘述). 而在全部删除测试数据后,相关的表与物理文件的对应在vacuum full 后会被改变(具体与vacuum full的原理有关), 这里文件找不到的问题主要是PG 产生了新的文件,但是并没有在数据表层面进行重新的更新信息造成的误会.