PG中的oid和relfilenode之间的关系

简介: PG中的oid和relfilenode之间的关系

PG中的oid和relfilenode之间的关系


PG中的表由一个relfilenode值,即磁盘上表的文件名(除了外表和分区表)。通常情况下可以在Pg_class表找到这个值,然而也会查考一些表的relfilenode为0.本文介绍这些表relfilenode的内部处理流程。


普通表的relfilenode


PG中创建一个表后,会在系统被pg_class存储它的relfilenode值。下面例子,表创建后,OID和relfilenode都时16808。还可以在磁盘上看到16808文件。

postgres=# create table t2(i int);
CREATE TABLE
postgres=# select oid,relname,relfilenode frompg_class where relname = 't2';
 oid  | relname | relfilenode
-------+---------+-------------
 16808 |t2      |       16808
(1 row)
postgres=# \q
movead@movead-PC:/h2/pgpgpg/bin$ ll../data/base/12835/16808
-rw-------+ 1 movead movead 0 12月 31 17:11../data/base/12835/16808
movead@movead-PC:/h2/pgpgpg/bin$
执行truncate、vacuum full等操作后,表数据被重写,并且表文件的relfilenode也会改变。下面测试显示了truncate后,t2的relfilenode值由16808变成16811.
postgres=# truncate t2;
TRUNCATE TABLE
postgres=# select oid,relname,relfilenode from pg_class where relname = 't2';
  oid  | relname | relfilenode
-------+---------+-------------
 16808 | t2      |       16811
(1 row)
postgres=# checkpoint;
CHECKPOINT
postgres=# \q
movead@movead-PC:/h2/pgpgpg/bin$ ll ../data/base/12835/16808
ls: 无法访问'../data/base/12835/16808': 没有那个文件或目录
movead@movead-PC:/h2/pgpgpg/bin$ ll ../data/base/12835/16811
-rw-------+ 1 movead movead 0 12月 31 17:16 ../data/base/12835/16811
movead@movead-PC:/h2/pgpgpg/bin$


nail表的relfilenode

postgres=# select oid, relname, relfilenode,reltablespace
from pg_class
where relfilenode = 0 and relkind = 'r'
order by reltablespace;
 oid  |        relname        | relfilenode | reltablespace
------+-----------------------+-------------+---------------
 1247 | pg_type               |           0 |             0
 1255 | pg_proc               |           0 |             0
 1249 | pg_attribute          |           0 |             0
 1259 | pg_class              |           0 |             0
 3592 | pg_shseclabel         |           0 |          1664
 1262 | pg_database           |           0 |          1664
 2964 | pg_db_role_setting    |           0 |          1664
 1213 | pg_tablespace         |           0 |          1664
 1261 | pg_auth_members       |           0 |          1664
 1214 | pg_shdepend           |           0 |          1664
 2396 | pg_shdescription      |           0 |          1664
 1260 | pg_authid             |           0 |          1664
 6000 | pg_replication_origin |           0 |          1664
 6100 | pg_subscription       |           0 |          1664
(14 rows)
postgres=#

上面的例子的查询可看到这些表的relfilenode都是0.pg_type、pg_proc、pg_attribute和pg_class是non-shared表,称为Nail表。剩余的表是pg_global表空间的shared表。

Pg_class表中的relfilenode字段告诉我们磁盘上存储的文件名是什么。例如在表t2上进行查询时,首先需要从pg_class中获取relfilenode,然后在磁盘上找到对于文件,接着才能进行打开和扫描。如果想查询磁盘上pg_class的文件名,那去哪里找relfilenode呢?有一系列函数提供了转换oid\relfilenode的函数。

postgres=# select pg_relation_filenode(1259);
 pg_relation_filenode
----------------------
                16475
(1 row)
postgres=# select pg_filenode_relation(0,16475);
 pg_filenode_relation
----------------------
 pg_class
(1 row)
postgres=# select pg_filenode_relation(0,16475)::oid;
 pg_filenode_relation
----------------------
                 1259
(1 row)
postgres=#

通过调用pg_relation_filenode(),oid可以转换成relfilenode;通过pg_filenode_relation()函数可以将relfilenode转换成oid。

Shared和nail表的oid和relfilenode之间的关系没有存储在pg_class表,PG如何存储这个映射关系呢?


Nail表的relfilenode存储机制


经过研究后,找到要给pg_filenode.map文件:

movead@movead-PC:/h2/pgpgpg/data/base/12835$ ll pg_filenode.map
-rw-------+ 1 movead movead 512 12月 31 15:10 pg_filenode.map
movead@movead-PC:/h2/pgpgpg/data/base/12835$
movead@movead-PC:/h2/pgpgpg/data/global$ ll pg_filenode.map
-rw-------+ 1 movead movead 512 12月 31 15:10 pg_filenode.map
movead@movead-PC:/h2/pgpgpg/data/global$
shared表的oid和relfilenode映射关系存储在global目录的pg_filenode.map中。Database为12835的nail表映射关系存储在12835目录的pg_filenode.map中。该文件存储的内容结构是:
typedef struct RelMapping
{
    Oid         mapoid;         /* OID of a catalog */
    Oid         mapfilenode;    /* its filenode number */
} RelMapping;
typedef struct RelMapFile
{
    int32       magic;          /* always RELMAPPER_FILEMAGIC */
    int32       num_mappings;   /* number of valid RelMapping entries */
    RelMapping  mappings[MAX_MAPPINGS];
    pg_crc32c   crc;            /* CRC of all above */
    int32       pad;            /* to make the struct size be 512 exactly */
} RelMapFile;


总结


本文主要介绍了PG的oid和relfilenode的两种表现方式,pg_relation_filenode()获取的值永远是正确的,但是从系统表中查询出的就可能是错误的。


原文


https://www.highgo.ca/2021/01/12/the-mapping-of-oid-and-relfilenode-in-pg/

目录
相关文章
|
SQL 关系型数据库 MySQL
将MySQL 数据迁移到 PostgreSQL
将MySQL 数据迁移到 PostgreSQL 可以采用以下步骤: 安装 PostgreSQL 数据库:首先,需要安装 PostgreSQL 数据库。可以从官方网站(https://www.postgresql.org/)下载最新版本的 PostgreSQL,并根据官方指南进行安装。 创建 PostgreSQL 数据库:在 PostgreSQL 中创建与 MySQL 数据库相对应的数据库。可以使用 pgAdmin 或命令行工具(如 psql)来创建数据库。例如,如果在 MySQL 中有一个名为 "mydb" 的数据库,那么可以在 PostgreSQL 中创建一个具有相同名称的数据库。 导
6302 0
|
机器学习/深度学习 文字识别 算法
文字识别OCR技术在表格识别方面的确已经取得了一些进展
文字识别OCR技术在表格识别方面的确已经取得了一些进展【1月更文挑战第24天】【1月更文挑战第117篇】
733 3
|
Oracle 安全 关系型数据库
如何在openGauss/PostgreSQL手动清理XLOG/WAL 文件?
openGauss/PostgreSQL中的预写式日志WAL(Write Ahead Log),又名Xlog或redo log,相当于oracle的online redo log, 不同的是oracle online redo log是提前创建几组滚动使用,但在opengauss中只需要本配置参数控制WAL日志的周期,数据库会一直的创建并自动清理,但存在一些情况WAL日志未清理导致目录空间耗尽,或目录空间紧张时手动删除wal日志时,比如如何确认在非归档模式下哪些WAL日志文件可以安全删除?
2208 0
|
存储 数据采集 监控
性能测试报告模板
本文档为某某某项目性能测试报告,主要内容包括概述、测试环境、测试方法、测试工具等。主要的读者有性能测试脚本开发人员、性能测试执行人员、性能评估人员、开发人员、项目经理、用户代表等。
6835 1
性能测试报告模板
|
存储 Rust 监控
使用 watchfiles 监控目录变更
使用 watchfiles 监控目录变更
622 2
|
Linux Shell
10-9|linux上统计文件中单词次数
10-9|linux上统计文件中单词次数
|
监控 Oracle 关系型数据库
性能监控之Telegraf+InfluxDB+Grafana+Python实现Oracle实时监控
【6月更文挑战14天】性能监控之Telegraf+InfluxDB+Grafana+Python实现Oracle实时监控
545 2
|
Linux Shell Docker
如何在Docker容器中使用巨页(大页)
在linux环境下常规页面大小是4K,常规巨页大小有两种一种是2MB,一种是1GB。巨页的好处是:减少硬件tlb miss,如此在连续内存访问场景下可以得到较大的性能提升。
5784 0
|
传感器 API Android开发
Qt 6.2 中的模块变更(从官网文档翻译)
Qt 6.2 中的模块变更(从官网文档翻译)
613 0
|
SQL 关系型数据库 数据库
PostgreSQL【应用 02】扩展SQL之C语言函数(编写、编译、载入)实例分享
PostgreSQL【应用 02】扩展SQL之C语言函数(编写、编译、载入)实例分享
720 0

热门文章

最新文章