介绍
怎么在PostgreSQL中对Oid和Relfilenode进行映射?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
正常表的Relfilenode
当我们创建一张普通表时,在pg_class系统表里可以查询出其Relfilenode,可以看出在表刚刚创建时其Oid和Relfilenode都是16808年,在磁盘上也可以查询到这16808个文件。事实上,这个文件存储了我们向表t2插入的数据。
postgres=#, create table t2(小姐:int); CREATE 表 postgres=#, select oid, relname, relfilenode 得到pg_class where relname =, & # 39; t2 # 39;; |,oid relname |, relfilenode - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - ,16808 |,t2 ,, |,,, 16808 (1,行) postgres=# \问 movead@movead-PC:美元/h3/pgpgpg/bin, ll . ./数据/基地/12835/16808 - - - - - - - - +,1,movead movead 0, 12月,31,17:11 . ./数据/基地/12835/16808 movead@movead-PC:/h3/pgpgpg/bin $
在我们对一张表执行截断,真空完整等操作后,会重写这个表的数据,会引发这个表relfilenode值的变更。如下测试可以看出截断之后,t2表的relfilenode从16808变为16811年了。
postgres=#, truncate t2; TRUNCATE 表 postgres=#, select oid, relname, relfilenode 得到pg_class where relname =, & # 39; t2 # 39;; |,oid relname |, relfilenode - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - ,16808 |,t2 ,, |,,, 16811 (1,行) postgres=#,检查点; 检查点 postgres=# \问 movead@movead-PC:美元/h3/pgpgpg/bin, ll . ./数据/基地/12835/16808 ls:无法访问& # 39;. ./数据/基地/12835/16808& # 39;:,没有那个文件或目录 movead@movead-PC:美元/h3/pgpgpg/bin, ll . ./数据/基地/12835/16811 - - - - - - - - +,1,movead movead 0, 12月,31,17:16 . ./数据/基地/12835/16811 movead@movead-PC:/h3/pgpgpg/bin $
指甲表的Relfilenode
postgres=#, select oid,, relname, Relfilenode, reltablespace 得到pg_class where relfilenode =, 0,以及relkind =, & # 39; " # 39; 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,行) postgres=#
上述查询可以看的出,从pg_class系统表中查询出的这些表的relfilenode为0。其中pg_type, pg_proc, pg_attribute, pg_class是非共享表,在内核中称他们为指甲表。剩余的表是在pg_global表空间里的共享表。
pg_class表中relfilenode字段的意义是为了告诉程序,某一张表在磁盘上存储的文件名。比如我们查询t2表时,一定会先到pg_class系统表中获取其relfilenode,然后到磁盘找到这个文件,然后打开并扫描。可是如果我们想查询pg_class系统表在磁盘上的文件名时,应该去哪找到它的relfilenode ?在PostgreSQL中提供了一组函数接口进行oid和relfilenode的转化。
postgres=#, select pg_relation_filenode (1259); ,pg_relation_filenode ---------------------- ,,,,,,,16475 (1,行) postgres=#, select pg_filenode_relation (0, 16475); ,pg_filenode_relation ---------------------- null null null null null null null null null null null null null null null null null null null null null null null null null null null null怎么在PostgreSQL中对Oid和Relfilenode进行映射