【PostgreSQL里pg_filenode.map文件的意义】

一、关于pg_filenode.map

通常情况下,PostgreSQL中每张表在磁盘上都有与之相关的文件,而这些文件的名字便是relfilenode,我们可以通过pg_class的relfilenode字段去查询。

postgres=# select relname,oid,relfilenode,reltablespace from pg_class where relname in ('pg_database','pg_class','pg_type','pg_namespace','pg_attribute','tab_1');

   relname    |  oid  | relfilenode | reltablespace
--------------+-------+-------------+---------------
 pg_type      |  1247 |           0 |             0
 tab_1        | 33125 |       33136 |             0
 pg_namespace |  2615 |        2615 |             0
 pg_database  |  1262 |           0 |          1664
 pg_attribute |  1249 |           0 |             0
 pg_class     |  1259 |           0 |             0
(6 rows)

对于一张普通表,其relfilenode和oid默认是一样的。系统表有的也是。但当我们对该表进行了例如vacuum full、truncate之类的操作,表重建后,那么relfilenode便会发生变化。

pg_class视图里,通过reltablespace字段我们也可以发现分为两类系统表:一类是pg_type、pg_attribute、pg_proc和pg_class,它们是非共享的表,在内核中我们称为Nail表。而另一类则是reltablespace为1664的,即在pg_global表空间里的共享表。

有一部分特殊的表我们会发现其对应的表relfilenode为0,官方文档的解释为:0表示这是一个“映射”关系,其磁盘文件名取决于底层状态。对于这种访问十分频繁的系统表,不希望每次都是从一些其它的系统表去查询,这样性能便会非常低,它们便是通过pg_filenode.map文件去进行管理的。pg_filenode.map在base的目录每个库的目录以及global目录下均有一个。

postgres@ubuntu-linux-22-04-desktop:~/data-16$ ll global/pg_filenode.map
-rw------- 1 postgres postgres 524 Dec 26 01:06 global/pg_filenode.map
postgres@ubuntu-linux-22-04-desktop:~/data-16$ ll base/*/pg_filenode.map
-rw------- 1 postgres postgres 524 Dec 26 01:06 base/1/pg_filenode.map
-rw------- 1 postgres postgres 524 Jan 17 10:40 base/13008/pg_filenode.map
-rw------- 1 postgres postgres 524 Dec 26 01:06 base/16385/pg_filenode.map
-rw------- 1 postgres postgres 524 Dec 26 01:06 base/4/pg_filenode.map

在global和base对应数据库的pg_filenode.map文件中,将这些系统表的oid与relfileno做映射,文件的大小为512,刚好是一个OS disk sector的大小。这个文件最多存放62条系统catalog表的记录

二、base目录对应数据库目录下的pg_filenode.map(非共享)

postgres@ubuntu-linux-22-04-desktop:~/data-16/base/13008$ pg_filedump -m pg_filenode.map

*******************************************************************
* PostgreSQL File/Block Formatted Dump Utility
*
* File: pg_filenode.map
* Options used: -m
*******************************************************************
Magic Number: 0x592717 (CORRECT)
Num Mappings: 17
Detailed Mappings list:
OID: 1259       Filenode: 41317
OID: 1249       Filenode: 1249
OID: 1255       Filenode: 1255
OID: 1247       Filenode: 1247
OID: 2836       Filenode: 2836
OID: 2837       Filenode: 2837
OID: 4171       Filenode: 4171
OID: 4172       Filenode: 4172
OID: 2690       Filenode: 2690
OID: 2691       Filenode: 2691
OID: 2703       Filenode: 2703
OID: 2704       Filenode: 2704
OID: 2658       Filenode: 2658
OID: 2659       Filenode: 2659
OID: 2662       Filenode: 41320
OID: 2663       Filenode: 41321
OID: 3455       Filenode: 41322

可以结合脚本过滤,原本数据库里系统表和oid的对应关系如下,其中pg_toast_1255和pg_toast_1247分别为pg_proc和pg_type的toast表

//拼接所有的oid,并加上相关字段,便于后边查询对象。
postgres@ubuntu-linux-22-04-desktop:~/data-16/base/13008$ pg_filedump -m pg_filenode.map | grep OID| awk '{print "or oid="$2}'|awk 'ORS=NR%17?" ":"\n"{print}'

or oid=1259 or oid=1249 or oid=1255 or oid=1247 or oid=2836 or oid=2837 or oid=4171 or oid=4172 or oid=2690 or oid=2691 or oid=2703 or oid=2704 or oid=2658 or oid=2659 or oid=2662 or oid=2663 or oid=3455

postgres=#  select relname,oid,relfilenode,reltablespace from pg_class where oid=1259 or oid=1249 or oid=1255 or oid=1247 or oid=2836 or oid=2837 or oid=4171 or oid=4172 or oid=2690 or oid=2691 or oid=2703 or oid=2704 or oid=2658 or oid=2659 or oid=2662 or oid=2663 or oid=3455;
              relname              | oid  | relfilenode | reltablespace
-----------------------------------+------+-------------+---------------
 pg_type                           | 1247 |           0 |             0
 pg_toast_1255                     | 2836 |           0 |             0
 pg_toast_1247                     | 4171 |           0 |             0
 pg_toast_1255_index               | 2837 |           0 |             0
 pg_toast_1247_index               | 4172 |           0 |             0
 pg_proc_oid_index                 | 2690 |           0 |             0
 pg_proc_proname_args_nsp_index    | 2691 |           0 |             0
 pg_type_oid_index                 | 2703 |           0 |             0
 pg_type_typname_nsp_index         | 2704 |           0 |             0
 pg_attribute_relid_attnam_index   | 2658 |           0 |             0
 pg_attribute_relid_attnum_index   | 2659 |           0 |             0
 pg_class_oid_index                | 2662 |           0 |             0
 pg_class_relname_nsp_index        
<think>好的,我现在需要回答用户关于PostgreSQLpg_tblspc目录位置以及pg_relation_filepath函数结果解析的问题。首先,我应该先回顾用户提供的引用内容,看看有哪些相关信息可以利用。 根据引用[3],当创建一个表空间时,会在$PGDATA/pg_tblspc目录下创建一个符号链接,链接到表空间的实际目录。这提到pg_tblspc位于$PGDATA下,也就是PostgreSQL的数据目录中。比如示例中的路径是/pgdata02/pg_tblspc/,而符号链接指向了/pg_tbs。所以,pg_tblspc的位置应该是$PGDATA/pg_tblspc,用户需要确认他们的PGDATA环境变量或者配置文件中的设置,通常默认是在/var/lib/postgresql/版本号/main或类似路径下。 接下来是pg_relation_filepath函数的作用,根据引用[1],这个函数返回指定关系的文件路径名。比如,如果表属于默认表空间(pg_default),那么文件路径会是相对于$PGDATA/base/数据库OID/关系filenode。但如果表在非默认表空间,路径就会涉及到pg_tblspc中的符号链接。例如,假设表空间的OID是16385,那么路径可能是pg_tblspc/16385/数据库OID/关系filenode。引用[2]中提到,普通表的relfilenode默认和OID相同,但某些操作如VACUUM FULL会改变relfilenode,这时候路径也会随之改变。 此外,引用[4]中提到的relfilenode为0的情况,这可能涉及到系统表,这些表可能存储在固定的位置或者有特殊的处理方式,所以pg_relation_filepath可能返回基于这些特殊处理的结果。例如,系统表的路径可能直接指向$PGDATA/global目录下的文件。 用户的问题还涉及到如何解析pg_relation_filepath的结果。比如,结果中的pg_tblspc/16385/12345/6789,需要拆解成各个部分:16385是表空间的OID,12345是数据库的OID,而6789是关系的relfilenode。这样就能找到实际的文件位置。 可能还需要解释表空间、数据库OID和relfilenode之间的关系。比如,每个数据库在表空间下有自己的目录,目录名是数据库的OID,而每个表或索引在该目录下以relfilenode文件名存储。对于默认表空间,路径是base,而非默认的则通过pg_tblspc中的符号链接定位。 总结来说,pg_tblspc目录位于PGDATA目录下,用于存储指向各个表空间的符号链接。pg_relation_filepath的结果则根据表所属的表空间不同,路径结构也不同。需要结合表空间OID、数据库OID和relfilenode来解析具体路径。同时,要注意relfilenode可能变化的情况,如执行VACUUM FULL等操作后,文件路径也会相应改变。 可能还需要提醒用户,如果误删了pg_filenode.map文件(如引用[4]提到的),可能会影响系统表的访问,这时候可能需要恢复或重建该文件,但具体情况可能需要更深入的步骤。 最后,根据用户的需求生成相关问题,可能需要包括如何查找表空间的实际路径,如何理解pg_relation_filepath的输出,relfilenode变化的影响,以及如何处理相关文件的问题等。</think>### PostgreSQL pg_tblspc 目录位置及 pg_relation_filepath 解析 #### 1. **pg_tblspc 目录位置** - **默认路径**:`pg_tblspc` 位于 PostgreSQL 的数据目录(`$PGDATA`)下,完整路径为 `$PGDATA/pg_tblspc`[^3]。 - **作用**:该目录存储所有非默认表空间的符号链接。每个符号链接的命名规则为表空间的 OID,指向表空间的实际存储路径。例如: ```bash # 示例路径 $PGDATA/pg_tblspc/16385 -> /custom_tablespace_path ``` 其中 `16385` 是表空间的 OID,`/custom_tablespace_path` 是用户定义的表空间物理路径。 #### 2. **pg_relation_filepath 结果解析** `pg_relation_filepath(relation_name)` 函数返回表或索引的物理文件路径,格式规则如下: - **默认表空间(pg_default)**: - 路径格式:`base/<database_oid>/<relfilenode>` - 示例:`base/12345/6789` 表示: - `12345`:数据库的 OID - `6789`:表的 relfilenode(通常与表 OID 相同,除非执行了 `VACUUM FULL` 等操作)[^2][^4]。 - **非默认表空间**: - 路径格式:`pg_tblspc/<tablespace_oid>/<database_oid>/<relfilenode>` - 示例:`pg_tblspc/16385/12345/6789` 表示: - `16385`:表空间的 OID - `12345`:数据库的 OID - `6789`:表的 relfilenode。 - **系统表特殊处理**: - 部分系统表(如 `pg_database`)的 `relfilenode` 为 `0`,其文件路径可能位于 `global` 目录下,例如 `global/1262`[^4]。 #### 3. **关键关联点** - **relfilenode 变化**:执行 `VACUUM FULL`、`TRUNCATE` 等操作后,表的 `relfilenode` 会更新,导致文件路径变化[^2]。 - **符号链接解析**:通过 `pg_tblspc` 中的符号链接,可以定位到表空间的实际存储位置。例如: ```sql -- 查询表空间的物理路径 SELECT pg_tablespace_location(oid) FROM pg_tablespace WHERE oid = 16385; ``` #### 示例分析 假设执行: ```sql SELECT pg_relation_filepath('my_table'); ``` 返回结果为 `pg_tblspc/16385/12345/33136`,则解析如下: 1. `pg_tblspc/16385`:表空间 OID 为 16385 的符号链接。 2. `12345`:数据库 OID。 3. `33136`:表的当前 relfilenode(可能因操作而变化)[^2][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小怪兽ysl

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值