场景:
当我们已知GaussDB A集群某个数据节点的一个relfilenode,想知道其对应数据库的Schema、表名
情况分类:
1、relfilenode对应表文件,且表非分区
2、relfilenode对应索引文件,且索引对应表非分区
3、relfilenode对应表文件,且表分区
4、relfilenode对应索引文件,且索引对应表分区
案例:
1、创建非分区表lhk及设置主键;创建分区表lhk_p及创建索引
create table public.lhk ( a int primary key, b text ); create table lhk.lhk_p ( a varchar(20), b text ) partition by range(a) ( partition p_start values less than('2021-01-01'), partition p_202101 values less than('2021-02-01'), partition p_202102 values less than('2021-03-01'), partition p_202103 values less than('2021-04-01'), partition p_end values less than(MAXVALUE) ); create index idx_lhk_p on lhk_p(a) local; |
2、创建自定义函数public.pg_relfilenode_find(relfilenode integer, node_name name)
自定义函数输出:Schema、表名、relfilenode对应分区表/索引名字、文件路径、备注
CREATE OR REPLACE FUNCTION public.pg_relfilenode_find(relfilenode integer, node_name name) RETURNS TABLE(pg_namespace_nspname name, pg_class_relname name, pg_partition_relname name, filepath text, mark text) LANGUAGE plpgsql NOT FENCED AS $$ DECLARE row_name1 record; row_name2 record; judge_str1 text; judge_str2 text; query_str1 text; query_str2 text; query_str3 text; query_str4 text; p1 text := 'Table and NO Partition'; --表文件且非分区表 p2 text := 'Table and Partition'; --表文件且分区表 p3 text := 'Index and Table NO partition'; --索引文件且非分区表的 p4 text := 'Index and Table Partition'; --索引文件且分区表的 BEGIN judge_str1 := 'EXECUTE DIRECT ON ('|| node_name ||')''select relkind, parttype from pg_class where relfilenode = '||relfilenode||';'''; --raise notice 'query_str1 is:% ',query_str1; FOR row_name1 IN EXECUTE(judge_str1) LOOP --表,单表 IF row_name1.relkind <> 'i' AND row_name1.parttype = 'n' THEN query_str1 := 'EXECUTE DIRECT ON ('|| node_name ||')''select n.nspname, c.relname, cast(''''/'''' as name), cast(pg_relation_filepath('|| relfilenode ||') as text), cast('''''|| p1 ||''''' as text) from pg_class c, pg_namespace n where c.relnamespace = n.oid and c.relfilenode = '|| relfilenode ||';'''; raise notice 'query_str1 is:% ',query_str1; RETURN QUERY EXECUTE (query_str1); END IF; --单表索引 IF row_name1.relkind = 'i' THEN query_str3 := 'EXECUTE DIRECT ON ('|| node_name ||')''select n.nspname, c2.relname, cast(''''/'''' as name), cast(pg_relation_filepath('|| relfilenode ||') as text), cast('''''|| p3 ||''''' as text) from pg_class c1, pg_index i, pg_class c2, pg_namespace n where c1.oid = i.indexrelid and i.indrelid = c2.oid and c2.relnamespace = n.oid and c1.relfilenode = '|| relfilenode ||';'''; raise notice 'query_str3 is:% ',query_str3; RETURN QUERY EXECUTE (query_str3); END IF; END LOOP; --表,分区表 judge_str2 := 'EXECUTE DIRECT ON ('|| node_name ||')''select parttype from pg_partition where relfilenode = '||relfilenode||';'''; FOR row_name2 IN EXECUTE(judge_str2) LOOP IF row_name2.parttype <> 'x' THEN query_str2 := 'EXECUTE DIRECT ON ('|| node_name ||')''select n.nspname, c.relname, p.relname, cast(pg_relation_filepath('|| relfilenode ||') as text), cast('''''|| p2 ||''''' as text) from pg_partition p, pg_namespace n, pg_class c where p.parentid = c.oid and c.relnamespace = n.oid and p.relfilenode = '|| relfilenode ||';'''; raise notice 'query_str2 is:% ',query_str2; RETURN QUERY EXECUTE (query_str2); ELSE --分区索引 query_str4 := 'EXECUTE DIRECT ON ('|| node_name ||')''select n.nspname, c.relname, p.relname, cast(pg_relation_filepath('|| relfilenode ||') as text), cast('''''|| p4 ||''''' as text) from pg_partition p, pg_namespace n, pg_class c, pg_index i where p.parentid = i.indexrelid and i.indrelid = c.oid and c.relnamespace = n.oid and p.relfilenode = '|| relfilenode ||';'''; raise notice 'query_str4 is:% ',query_str4; RETURN QUERY EXECUTE (query_str4); END IF; END LOOP; END;$$ |
3、在测试数据节点dn_6001_6002获取测试用relfilenode
1>、lhk表relfilenode--732887 2>、lhk表主键索引relfilenode--732893 3>、lhk_p分区表relfilenode--741099、741100、741101、741097、741098 4>、lhk_p分区表索引relfilenode--741118、741119、741120、741121、741122 |
4、使用自定义函数查询
1>、relfilenode对应表文件,且表非分区 select * from public.pg_relfilenode_find(732887,'dn_6001_6002');
2>、relfilenode对应索引文件,且索引对应表非分区
select * from public.pg_relfilenode_find(732893,'dn_6001_6002');
3>、relfilenode对应表文件,且表分区 select * from public.pg_relfilenode_find(741100,'dn_6001_6002');
4>、relfilenode对应索引文件,且索引对应表分区 select * from public.pg_relfilenode_find(741119,'dn_6001_6002');
|
5、如果函数没有找到数据,则可参考以下链接第5、6步骤查询判断
注:
-
文件如143345_bcm, 143345_C1.0, 143345.1的relfilenode都是143345;其中_bcm是特殊的文件后缀,_C1表示是列存表第一列对应的文件,*.1表示文件超过1G后新建的文件;
-
不同实例下相同表的relfilenode可能不同;
-
每个数据库下都有pg_class和pg_partition的系统表
-
一定要确保连接正确的实例和数据库
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)