一个filenode
是一个唯一的数字标识符,用于命名属于关系的磁盘上文件。它存储在关系的pg_class条目的relfilenode
列中,数据类型为OID。
当创建关系时,relfilenode
与关系的OID相同,但如果关系被重写(例如,在VACUUM FULL
或TRUNCATE
之后),它将发生变化。
请参见下面的函数,以帮助将filenode ID映射到关系,反之亦然。
函数
PostgreSQL提供以下函数来帮助将filenode ID映射到关系
pg_relation_filenode(
relation
regclass
)pg_filenode_relation(
tablespace
oid
,filenode
oid
)
pg_relation_filenode()
返回指定对象的filenode编号。此外,pg_relation_filepath()
将提供完整的filenode路径(相对于PGDATA)。
pg_filenode_relation()
返回与指定表空间(值为0
表示默认表空间)和filenode关联的关系的OID。
此外,contrib模块 oid2name
也可用于将数据目录中的OID和filenode映射到对象名称。
relfilenode = 0
如果pg_class
中关系的relfilenode列为0,则表示它是一个“映射”关系,其磁盘文件名通过pg_filenode.map在较低级别确定;实际上,这意味着pg_catalog模式中的表。
源代码
内部使用RelFileNode
结构体来引用filenode;请参见src/include/storage/relfilenode.h
typedef struct RelFileNode { Oid spcNode; /* tablespace */ Oid dbNode; /* database */ Oid relNode; /* relation */ } RelFileNode;
这使后端能够确定缓冲区页的磁盘位置,而无需了解其底层表;例如,请参见src/include/storage/buf_internals.h中的注释。
示例
postgres=# CREATE TABLE filenode_test (id INT); CREATE TABLE postgres=# SELECT oid, relfilenode FROM pg_class WHERE relname='filenode_test'; oid | relfilenode -------+------------- 16461 | 16461
这里,oid
和relfilenode
是相同的。在完全重写之后,例如使用VACUUM FULL,这种情况会发生变化。
postgres=# VACUUM FULL filenode_test; postgres=# SELECT oid, relfilenode FROM pg_class WHERE relname='filenode_test'; oid | relfilenode -------+------------- 16461 | 16464 (1 row)
函数
从关系中提取filenode信息
postgres=# SELECT oid, relfilenode, pg_relation_filenode(relname::regclass), pg_relation_filepath(relname::regclass) FROM pg_class WHERE relname='filenode_test'; oid | relfilenode | pg_relation_filenode | pg_relation_filepath -------+-------------+----------------------+---------------------- 16461 | 16464 | 16464 | base/13285/16464 (1 row)
从filenode中提取关系信息
postgres=# SELECT pg_filenode_relation(0, 16464)::oid,
pg_filenode_relation(0, 16464); pg_filenode_relation | pg_filenode_relation ----------------------+---------------------- 16461 | filenode_test (1 row)
确定一组filenode ID是否属于当前数据库中表空间中的关系
postgres=# WITH a(x) AS (VALUES (16452), (16468)) SELECT pg_filenode_relation(0, x)::REGCLASS FROM a;
0
是默认表空间;根据需要替换为非默认表空间OID。