一个filenode
(文件节点)是用于命名关系(relation)在磁盘上的文件的唯一数字标识符。它以OID数据类型存储在关系的pg_class条目中的relfilenode
列里。
当关系被创建时,relfilenode
与其关系的OID相同,但在关系被重写后(例如,在执行VACUUM FULL
或TRUNCATE
之后),它会发生变化。
有关帮助映射文件节点 ID 到关系的以及反向映射的函数,请参见下文。
函数
PostgreSQL提供了以下函数来帮助映射文件节点 ID 到关系:
pg_relation_filenode(
relation
regclass
)pg_filenode_relation(
tablespace
oid
,filenode
oid
)
pg_relation_filenode()
函数返回指定对象的节点号。此外,pg_relation_filepath()
函数会提供完整的文件节点路径(相对于PGDATA)。
pg_filenode_relation()
函数返回与指定表空间(值为0
表示默认表空间)和文件节点相关联的关系的OID。
此外,contrib模块 oid2name
也可以用于将数据目录中的OID和文件节点映射到对象名称。
relfilenode = 0
如果在pg_class
中,关系的relfilenode列为0,则表示这是一个“映射”(mapped)关系,其磁盘上的文件名由pg_filenode.map在较低级别确定;实际上,这通常意味着pg_catalog模式中的表。
源代码
内部使用RelFileNode
结构体来引用文件节点;请参见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)
函数
从关系中提取文件节点信息
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)
从文件节点中提取关系信息
postgres=# SELECT pg_filenode_relation(0, 16464)::oid,
pg_filenode_relation(0, 16464); pg_filenode_relation | pg_filenode_relation ----------------------+---------------------- 16461 | filenode_test (1 row)
确定一组文件节点 ID 是否属于当前数据库中某个表空间中的关系。
postgres=# WITH a(x) AS (VALUES (16452), (16468)) SELECT pg_filenode_relation(0, x)::REGCLASS FROM a;
0
是默认表空间;如有需要,请替换为非默认表空间的OID。