数据库postgresql元数据管理

上传人:工**** 文档编号:552659175 上传时间:2024-02-14 格式:DOCX 页数:7 大小:31.44KB
返回 下载 相关 举报
数据库postgresql元数据管理_第1页
第1页 / 共7页
数据库postgresql元数据管理_第2页
第2页 / 共7页
数据库postgresql元数据管理_第3页
第3页 / 共7页
数据库postgresql元数据管理_第4页
第4页 / 共7页
数据库postgresql元数据管理_第5页
第5页 / 共7页
点击查看更多>>
资源描述

《数据库postgresql元数据管理》由会员分享,可在线阅读,更多相关《数据库postgresql元数据管理(7页珍藏版)》请在金锄头文库上搜索。

1、别人都说,写博客可以帮助自己管理和整理以前知识,自己也来写自己的第一篇博客。前一段时间都在看 postgresql 的元数据管理,趁着还没有忘,敢快总结一下,算是自 己的第一篇博客。一、 元数据的概念先讲一下概念,或者说统一一下用语,什么是元数据,me tada ta。这里讲的元数据其 实就是平时在数据库也叫“数据字典”,也有叫“系统表”。因为作者以前并没有直接用过 数据库,是直接看postgresql的代码学习数据库的,所以对于这些名称到底该叫什么不是 非常清楚,这里就统一叫元数据(me tada ta)。元数据是什么呢?在我的理解来看,元数据就是管理数据的数据,它记录了数据库里面 的数据是

2、如何定义、如何组织等等。元数据的格式在postgresql里面,元数据是以系统表的形式存放在磁盘。系统表其实与用户的普通表 并没有太大区别,一个表由几个column组成,每一个column都有自己的数据类型。对于系 统表的访问同样遵循ACID的特性。这里我们拿pg_namespace来作为例子。Table 45-30.space ColUI Illi IISNfimeTyp(ReferencesDescriptionnaTLeMtjne of Uih ridrTiebJdLt!nspowneroidpg aucliid :Ownsr of tlisEi3K)aclacliLeix:Accysb

3、 privi沁匕 GRANT dnd REVOKE F(ji detdilbPg_namespace记录了一个database实例中所有namespace(schema)的信息。(元数据从 是否在不同 database 共享方面分为两种,一类是共享元数据,也就是在所有的 database 中 只有一个元数据表,比如pg_database,另外一种是在每一个database都有一份单独的实例, 比如现在讲的pg_namespace,它在每一个database实例中都有一个)Pg_namespace的每一行,也就是每一个tuple都记录一个namespace的信息,nspname 记录了它的名称,

4、而它的数据类型是name,而nspowner记录这个namespace的owner,类 型是oid,它其实参照了另外一张元数据表pg_authid的一列。Pg_authid是记录了数据库中 每一个 user 的信息。 Napacl 记录关于这个 namespace 的一些权限。比如用户输入: select * from tom.t1 ; postgresql 在解析这条语句的时候,就会去查 pg_namespace 这张表里面,是否有一个名称为 tom 的 namespace。*r.it jl/4i三、 元数据的 cache我们在这里把元数据管理当作 postgresql 的一个模块。它的代码

5、在 srcbackendcatalo 下面。其它模块读取元数据的时候,并不是直接去通过扫描系统表来访问元数据,而是通过 元数据的 cache 来访问的。为什么cache?因为对于元数据的访问是非常频繁,而元数据是在以表的形式存放在磁 盘里面,如果每一次读取元数据都去访问磁盘,那么对于元数据的访问就会成为系统性能的 瓶颈,所以这里需要把经常使用到的元数据的放到内存。那么cache的格式是什么样子? cache与系统表的关系呢? cache的单位是什么?下面会 围绕这三个问题慢慢道来。我们首先弄清楚元数据是如何访问的?这里还拿 pg_namespace 来作例子。一般对于 namespace元数据

6、的访问就像前面讲的,在解析SQL语句的时候,会通过一个字符串来查 database中是否有这个namespace?如果有,那它的OID是什么? 或者在返回给用户一 些错误信息的时候,通过namespace的oid来查这个namespace的字符串表示是什么?或者 通过 namespace 的 oid 来获得它的 ACL 列表,来进行权限检查。 其实最简单的就是,要么 通过namespace的名称来获得这个这个namespace的pg_namespace中的一个,也就是这个 namespace对应的tuple。或者通过oid来拿到这个namespace对应的tuple。这里还是拿pg_names

7、pace来举例子,元数据的cache其实就是在内存中的一个hash表。 Hash的key就是一个或几个列的值,而value就是对应一个元数据表的tuple。那这里面又 引出一业个问题,用户在使用pg_namespace的时候,可能根据一个namespace的字符串来 查,也有可能根据一个 namespace 的 oid 来查,一个 hash 表能实现吗? 这里就引出来我 们第二个问题:cache与系统表的关系? 一个系统表的cache有可能是多个hash表,hash 表的value都是对应该系统表的一个tuple,而key值不同。对于pg_namespace来讲,它的 cache在内存中就有两

8、个hash表。在syscache.h的SysCacheldentifier中,它列出来所有作为 元数据 cache 的 hash 表的 id, 其中 NAMESPACENAME, NAMESPACEOID 就是对应 pg_namespace 的两个 hash 表, NAMESPACENAME 的 key 是以 namespace 的字符串,而 NAMESPACEOID 的 key 值是 namespace 的 oid。anumAGGFJTOTD = 0fAHOIDr AMOPOPID, AMOPSTEiATEGY, AMPROCWUMf ATTNAMEf ATTMUM, AUTHMEMMEMR

9、OLE:,从上面的描述其实基本上已经回答了三个问题,那么cache的格式是什么样子? cache 与系统表的关系呢? cache的单位是什么?这里再啰嗦一下。Cache 的格式是什么?元数据cache以hash表的格式对系统表进行cache, key值对应系统表的一个或者多个列, value就是它对应系统表的一行或者说一个tupleCache 与系统表的关系?一个hash表只能对应一个系统表,但是一个系统表可能对应多个hash表。Cache 的单位是什么?因为是以hash表作为cache的,这里cache的最小单位就是系统表的一行,这就意味 着, cache并不需要把整张系统表加载到内存,只需

10、要把系统表中使用过的行加载到内存即 可。这里介绍几个与 cache 相关的结构体。第一个 SysCacheldentifier它枚举了 postgresql 所有的 cache 的 hash 表。 第二个 CatCache ,它是表示一个 hash 表。第三个catctup,它表示hash表里面的一个value值,也就是一个tuple详细的内容可以参见代码。四、Cache 的同步这里讲的同步有两层意义 本身作为cache,它需要与真正存放在磁盘的系统表的内容保持一致 不同session之间cache的同步 第一层意思比较简单,作为cache,它的内容应该与它的源的内容保持一致,前面讲了,其 它

11、模块在使用cache的时候,都是读它的内容,且cache是读元数据的唯一一个入口。但是 用户修改或者删除元数据是直接通过操作系统表来完成的,那么cache中的数据如何与系统 表的内容保持一致? 这里还是需要先介绍一点背景知识,在postgresqI里面,每一条命令都是一个事务内执行的, 一个事务可以执行多个命令。这里还是举例说明。假如有以下命令一00001: begin;00002:00003: C匚eate table t1 (cl int);00004:00005: Insert into 七1 ValUGS (100);00006:QQQQ7: select 大 from tl;0000

12、8:00009: drop tabl已 tl;00010:0 0011: 在 begin 与 commit 之间的命令都属于一个事务。如果没有显式的begin与commit命令,如下图:00014 : Create tabl已 t1 (cl int);00015:00016: Insert into tl VHlUQS (100);00017 :00018:5已丄已ct * f匚om tl;00019:00020 : drop table tl ;|门门门o1那这里的每一条命令都在一个事务里执行,上面四条命令也就是会有四个事务。Postgresql在一条命令中,比如create table t

13、1,在它的执行过程中,如果修改了元数据(删除、 增加、修改),并没有直接在hash表中修改已经被cached tuple,会向一个队列(translnvallnfo. CurrentCmdlnvalidMsgs)中写入一条 invalidation 消息,比如create table tl 这条命令在执行 过程中会向 pg_class 这张元数据表中增加一行,在元数据表增加一行后,它会向队列 translnvallnfo. CurrentCmdlnvalidMsgs 中写入一条消息。 而在一条命令快结束的时候, postgresql会读岀来transInvalInfo. CurrentCmdI

14、nvalidMsgs队列所有的消息,如果队列中消息 关联的tuple有被cached,那么它就会被从cache中删除。这样下一条命令再来从cache读取元数据的时候,会发现cache中没有这一条元数据信息,然后cache模块会从系统表中重新加载这一行,这样就实现 cache 与系统表之间内容的同步。换句话讲,系统表与cache之间的内容并不是实时同步,它们同步的单位是一条命令。还是有一个例子说明,假设系统里面已经存在一张表,名字叫t1。000010000200003000040000500006000070000900009begin;select * from tl; drop tab丄q

15、tl;select * from tl;commit;我们知道, pg_class 这张元数据表记录了系统所有 relation 的信息,这个 relation 包括 table 、sequence、index 等等。 Cache 中有两个 hash 对它进行 cache, 分别是RELNAMENSP,RELOID,RELNAMENSP 使用 namespace + table name 作索引Reloid使用table oid作索弓I当命令执行select * from t1第3行的时候,因为它是一个查询语句,并不会修改元数据 表,但是因为它使用到表t1,它会导致描述t1的tuple被加载到RELNAMENSP和RELOID两 个cache中。我们姑且把这个tuple叫做tuple_t1,那么现在tuple_t1共有三份,一份在系统 表中,另外两份分别在 RELNAMENSP 与 RELOID 中。接着我们执行第二条命令 drop table t1 , 在这条命令执行过程中,会删除系统表那一份 tuple_t1,且把能够标识tuple_t1 的信息写到translnvallnfo. CurrentCmdlnvalidMsgs 队列中去。 在这个命令结束的时候,postgresql 会从 transInvalInfo. Current

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号