数据库postgresql元数据管理.docx
文本预览下载声明
别人都说,写博客可以帮助自己管理和整理以前知识,自己也来写自己的第一篇博客。前一段时间都在看postgresql的元数据管理,趁着还没有忘,敢快总结一下,算是自己的第一篇博客。元数据的概念先讲一下概念,或者说统一一下用语,什么是元数据,metadata。 这里讲的元数据其实就是平时在数据库也叫“数据字典”,也有叫“系统表”。因为作者以前并没有直接用过数据库,是直接看postgresql的代码学习数据库的,所以对于这些名称到底该叫什么不是非常清楚,这里就统一叫元数据(metadata)。 元数据是什么呢?在我的理解来看,元数据就是管理数据的数据,它记录了数据库里面的数据是如何定义、如何组织等等。元数据的格式在postgresql里面,元数据是以系统表的形式存放在磁盘。系统表其实与用户的普通表并没有太大区别,一个表由几个column组成,每一个column都有自己的数据类型。对于系统表的访问同样遵循ACID的特性。这里我们拿pg_namespace来作为例子。Pg_namespace记录了一个database实例中所有namespace(schema)的信息。(元数据从是否在不同database共享方面分为两种,一类是共享元数据,也就是在所有的database中只有一个元数据表,比如pg_database, 另外一种是在每一个database都有一份单独的实例,比如现在讲的pg_namespace,它在每一个database实例中都有一个)Pg_namespace的每一行,也就是每一个tuple都记录一个namespace的信息,nspname记录了它的名称,而它的数据类型是name, 而nspowner记录这个namespace的owner,类型是oid,它其实参照了另外一张元数据表pg_authid的一列。Pg_authid是记录了数据库中每一个user的信息。Napacl记录关于这个namespace的一些权限。比如用户输入:select * from tom.t1 ; postgresql在解析这条语句的时候,就会去查pg_namespace这张表里面,是否有一个名称为tom的namespace。元数据的cache我们在这里把元数据管理当作postgresql的一个模块。它的代码在src\backend\catalo下面。其它模块读取元数据的时候,并不是直接去通过扫描系统表来访问元数据,而是通过元数据的cache来访问的。为什么cache?因为对于元数据的访问是非常频繁,而元数据是在以表的形式存放在磁盘里面,如果每一次读取元数据都去访问磁盘,那么对于元数据的访问就会成为系统性能的瓶颈,所以这里需要把经常使用到的元数据的放到内存。那么cache的格式是什么样子?cache与系统表的关系呢?cache的单位是什么?下面会围绕这三个问题慢慢道来。我们首先弄清楚元数据是如何访问的?这里还拿pg_namespace来作例子。一般对于namespace元数据的访问就像前面讲的,在解析SQL语句的时候,会通过一个字符串来查database中是否有这个namespace?如果有,那它的OID是什么?或者在返回给用户一些错误信息的时候,通过namespace的oid来查这个namespace的字符串表示是什么?或者通过namespace的oid来获得它的ACL列表,来进行权限检查。其实最简单的就是,要么通过namespace的名称来获得这个这个namespace的pg_namespace中的一个,也就是这个namespace对应的tuple。或者通过oid来拿到这个namespace对应的tuple。这里还是拿pg_namespace来举例子,元数据的cache其实就是在内存中的一个hash表。Hash的key就是一个或几个列的值,而value就是对应一个元数据表的tuple。那这里面又引出一业个问题,用户在使用pg_namespace的时候,可能根据一个namespace的字符串来查,也有可能根据一个namespace的oid来查,一个hash表能实现吗?这里就引出来我们第二个问题:cache与系统表的关系?一个系统表的cache有可能是多个hash表, hash表的value都是对应该系统表的一个tuple,而key值不同。对于pg_namespace来讲,它的cache在内存中就有两个hash表。在syscache.h的SysCacheIdentifier中,它列出来所有作为元数据cache的hash表的id, 其中NAMESPACENAME,NAMESPACEOID就是对应pg_namespace的两个hash表,NAMESPACENAME的key是以namespace的字符串,而NAMESPACEOID的key值是namespac
显示全部