一个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。