postgresql中根据oid和filenode去找表的物理文件的位置

时间:2022-08-12 12:23:53
1.新建一张表
postgres=# create table a(a int);
CREATE TABLE
postgres=# select oid,relfilenode from pg_class where relname='a';
oid | relfilenode
-------+-------------
17107 | 17107
(1 row)
我们会发现,oid和filenode对应的值是一样的,去找一下对应表的物理文件
[postgres@node2 13269]$ ls -l 17107
-rw-------. 1 postgres postgres 0 Mar 20 06:43 17107
[postgres@node2 13269]$ pwd
/home/postgres/data/base/13269
可以发现,我们可以找到想对应的物理文件
去看一下,我之前建的一张表
postgres=# select oid,relfilenode from pg_class where relname='test';
oid | relfilenode
-------+-------------
16478 | 16499
(1 row)
发现oid和filenode对应的值不一样。
先查看数据库的oid
postgres=# select oid,datname from pg_database ;
oid | datname
-------+-----------
13269 | postgres
1 | template1
13268 | template0
16466 | test
17096 | database
(5 rows)
去找一下物理文件
[postgres@node2 13269]$ ls -l 16478
ls: cannot access 16478: No such file or directory
[postgres@node2 13269]$ pwd
/home/postgres/data/base/13269
[postgres@node2 13269]$ ls -l 16499
-rw-------. 1 postgres postgres 229376 Mar 14 13:56 16499
[postgres@node2 13269]$ pwd
/home/postgres/data/base/13269
可以看出来我们根据oid找不到对应的物理文件,而根据filenode就找到了。
原因:
我们在对表进行过truncate或者vacuum操作以后,oid是不变的,而filenode是发生变化的
postgres=# insert into a select generate_series(1,100);
INSERT 0 100
postgres=# select oid,relfilenode from pg_class where relname='a';
oid | relfilenode
-------+-------------
17107 | 17107
(1 row)

postgres=# truncate a;
TRUNCATE TABLE
postgres=# select oid,relfilenode from pg_class where relname='a';
oid | relfilenode
-------+-------------
17107 | 17110
(1 row)


postgres=# insert into a select generate_series(101,200);
INSERT 0 100
postgres=# delete from a;
DELETE 100
postgres=# select oid,relfilenode from pg_class where relname='a';
oid | relfilenode
-------+-------------
17107 | 17110
(1 row)
postgres=# vacuum full a;
VACUUM
postgres=# select oid,relfilenode from pg_class where relname='a';
oid | relfilenode
-------+-------------
17107 | 17111
(1 row)
所以根据oid去查找表的物理文件的位置是不靠谱的事情。

2.查找表物理文件的方式:
postgres=# select pg_relation_filepath('a');
pg_relation_filepath
----------------------
base/13269/17111
(1 row)
另一种方式为通过oid2name
[postgres@node2 contrib]$ oid2name
All databases:
Oid Database Name Tablespace
----------------------------------
17096 database pg_default
13269 postgres pg_default
13268 template0 pg_default
1 template1 pg_default
16466 test pg_default
[postgres@node2 contrib]$ oid2name -d postgres
From database "postgres":
Filenode Table Name
----------------------------
17111 a
16493 lineitem
17089 pgbench_accounts
17086 pgbench_branches
17077 pgbench_history
17080 pgbench_tellers
16484 t3
16499 test
16490 ticket1
如果没有oid2name则需要去postgresql解压目录下的contrib安装一下,make, make install