数据库postgresql元数据管理
更新时间:2024-03-31 20:12:01 阅读量: 综合文库 文档下载
别人都说,写博客可以帮助自己管理和整理以前知识,自己也来写自己的第一篇博客。
前一段时间都在看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值是namespace的oid。
从上面的描述其实基本上已经回答了三个问题,那么cache的格式是什么样子?cache与系统表的关系呢?cache的单位是什么?
这里再啰嗦一下。 Cache的格式是什么?
元数据cache以hash表的格式对系统表进行cache, key值对应系统表的一个或者多个列,value就是它对应系统表的一行或者说一个tuple
Cache与系统表的关系?
一个hash表只能对应一个系统表,但是一个系统表可能对应多个hash表。
Cache的单位是什么?
因为是以hash表作为cache的,这里cache的最小单位就是系统表的一行,这就意味着,cache并不需要把整张系统表加载到内存,只需要把系统表中使用过的行加载到内存即可。
这里介绍几个与cache相关的结构体。
第一个SysCacheIdentifier,它枚举了postgresql所有的cache的hash表。 第二个CatCache ,它是表示一个hash表。
第三个catctup ,它表示hash 表里面的一个value值,也就是一个tuple
详细的内容可以参见代码。
四、 Cache的同步
这里讲的同步有两层意义 ? ?
本身作为cache,它需要与真正存放在磁盘的系统表的内容保持一致 不同session之间cache的同步
第一层意思比较简单,作为cache,它的内容应该与它的源的内容保持一致,前面讲了,其它模块在使用cache的时候,都是读它的内容,且cache是读元数据的唯一一个入口。但是
用户修改或者删除元数据是直接通过操作系统表来完成的,那么cache中的数据如何与系统表的内容保持一致?
这里还是需要先介绍一点背景知识,在postgresql里面,每一条命令都是一个事务内执行的,一个事务可以执行多个命令。
这里还是举例说明。假如有以下命令
在begin与commit之间的命令都属于一个事务。
如果没有显式的begin 与commit命令,如下图:
那这里的每一条命令都在一个事务里执行,上面四条命令也就是会有四个事务。
Postgresql在一条命令中,比如create table t1,在它的执行过程中,如果修改了元数据(删除、增加、修改),并没有直接在hash表中修改已经被cached tuple,会向一个队列(transInvalInfo. CurrentCmdInvalidMsgs)中写入一条invalidation消息, 比如create table t1这条命令在执行过程中会向pg_class这张元数据表中增加一行,在元数据表增加一行后,它会向队列transInvalInfo. CurrentCmdInvalidMsgs中写入一条消息。 而在一条命令快结束的时候,postgresql会读出来transInvalInfo. CurrentCmdInvalidMsgs队列所有的消息,如果队列中消息
关联的tuple有被cached,那么它就会被从cache中删除。。 这样下一条命令再来从cache读取元数据的时候,会发现cache中没有这一条元数据信息,然后cache模块会从系统表中
重新加载这一行,这样就实现cache与系统表之间内容的同步。
换句话讲,系统表与cache之间的内容并不是实时同步,它们同步的单位是一条命令。 还是有一个例子说明,假设系统里面已经存在一张表,名字叫t1。
我们知道,pg_class这张元数据表记录了系统所有relation的信息,这个relation包括
table 、sequence、index等等。Cache中有两个hash对它进行cache,分别是 RELNAMENSP, RELOID,
RELNAMENSP使用namespace + table name作索引 Reloid使用 table oid作索引
当命令执行select * from t1第3行的时候,因为它是一个查询语句,并不会修改元数据表,但是因为它使用到表t1,它会导致描述t1的tuple被加载到RELNAMENSP和RELOID两个cache中。我们姑且把这个tuple叫做tuple_t1,那么现在tuple_t1共有三份,一份在系统表中,另外两份分别在RELNAMENSP与RELOID中。 接着我们执行第二条命令 drop table t1 , 在这条命令执行过程中,会删除系统表那一份tuple_t1, 且把能够标识tuple_t1的信息写到transInvalInfo. CurrentCmdInvalidMsgs 队列中去。在这个命令结束的时候,postgresql会从transInvalInfo. CurrentCmdInvalidMsgs读到tuple_t1的标识信息,并且根据标识信息,删除RELNAMENSP RELOID被cache的tuple_t1
接下来再执行select * from t1, 这个时候,postgresql会从RELNAMENSP去读取t1的信息,发现cache中没有t1的信息,cache会去读系统表pg_class,发现系统也没有tuple_t1,然就告诉其它解析模块,系统中现在并没有叫t1的表。
第二层意思比较难理解:不同session之间元数据cache的同步
这里还是先介绍一些背景知识,我们知道postgresql是多进程结构,每一个session都
对应一个backend进程,元数据表是在多个session进程之间是共享的,但是元数据的cache在进程之间并不是共享的,而是每一个进程都有自己的每一份私有的cache,我想这样做的好处就是:
? ?
用空间去换时间,每一份进程私有一份cache,那么在读取cache的时候就不用加锁,效率会更快一点。
Cache可以不用关心多版本的问题。 在并发的事务中,不同事务在同一个时间点看到的元数据并不一定是相同的。举个例子,在我在事务A是执行了drop table t1, 在这个事务没有提交前,事务B以执行select * from t1 , 在这个时候,事务A在执行以drop table t1,它以后的命令应该看到的描述t1的元数据已经不存在了, 但是对于事务B来讲,因为事务A还没有提交,它应该看到表t1还是存在的。 如果元数据是在多个进程之间共享的话,它就还需要解决这一个问题。
正是因为postgresql的元数据cache并不是进程之间共享的,所以就有进程之间元数据cache同步的问题。
这里先简单描述一下,后面用例子说明。
Postgresql在每一个命令结束的时候,不仅根据transInvalInfo. CurrentCmdInvalidMsgs队列的信息,把本地的cache删除,它还把transInvalInfo. CurrentCmdInvalidMsgs追加到transInvalInfo. PriorCmdInvalidMsgs这个队列之中。 当一个事务结束的时候,会把transInvalInfo. PriorCmdInvalidMsgs队列所有的消息写到共享内存的队列中。Postgresql在每一命令开始执行之前,都会到共享内存的队列中读取消息,通过读到的消息,删除以应自己cache中的tuple。
下面还是举例说明,假设已经存在table t1 时间点 1 2 3 4 5 6 7 8
上表是说明在两个在不同session同时执行的事务.
在时间点3, sesson2 查询t1,同时把描述t1的元数据加载到自己的cache
在时间点4 session1执行了drop table t1,它把t1的invalidation信息写到自己的transInvalInfo. PriorCmdInvalidMsgs队列中。
在时间点5 session2 执行select * from t1,在执行之前,共享内存还没有t1元数据的invalidation的消息,它仍然能够读到t1在cache中的元数据。
在时间点6 session1 commit导致t1的invalidation的消息写到共享内存中。
在时间点7 在命令开始前,从共享内存读到t1元数据失效的信息,process2会删除cache中关于t1的元数据,所以命令解析过程中,会报找不到t1这张表。
Session1/process1 Begin; Drop table t1; Commit; Sesson2/process2 Begin; Select * from t1 Select * from t1 Select * from t1 Commit;
五、 总结一下
? ? ? ?
在不同的进程之间元数据的同步是通过共享内存的消息队列完成的。 Postgresql也是以表的形式来保存元数据的,记录元数据的表叫系统表。
为了加速元数据的访问,元数据以hash 表的方式,对系统表进行cache,一个系统表因为hash key的不同,可以对应多个hash 表。
元数据的cache在不同的进程之间是私有的,相互独立互不影响。
正在阅读:
数据库postgresql元数据管理03-31
服装店铺实习报告09-16
RNA干扰10-19
苏教版 3 年级上册同步作文训练04-27
《医学理论与实践》杂志投稿须知07-24
关于控制我市优质生源外流的调查与思考05-06
做人要积极乐观作文500字06-18
新民主主义论 毛概读书笔记03-08
美丽的桃花作文500字07-12
253《设计素描》教学大纲08-18
- 《江苏省环境水质(地表水)自动监测预警系统运行管理办法(试行)》
- 安乐死合法化辩论赛立论稿(浙大新生赛)
- 公共科目模拟试卷公务员考试资料
- 我国固定资产投资FAI对GDP的影响
- 大学生创新创业训练计划项目申请书大创项目申报表
- 完美版—单片机控制步进电机
- 2013资阳中考化学试题
- 18.两位数减一位数退位(397道)
- 工程量计算规则
- 二年级操行评语(下)
- 第3章 流程控制语句
- 浅基桥墩加固技术
- 课题研究的主要方法
- 5100软件说明书 - 图文
- 车间技术员年终总结
- 关于印发《中铁建工集团开展项目管理实验室活动方案》的通知
- 经典诵读结题报告
- 地下水动力学习题答案
- 2018年全国各地高考数学模拟试题平面解析几何试题汇编(含答案解
- 街道办事处主任2018年度述职述廉报告
- 数据管理
- postgresql
- 数据库
- PHC桩施工的质量通病及预防措施1
- 沃尔玛在中国的现状及发展趋势
- 2014年上海市初中毕业统一学业考试模拟考试化学试卷12
- 中华人民共和国核行业标准水中总放射性浓度的测定厚源法
- 实验报告四
- Linux虚拟机安装手册
- 建筑安全管理规定试卷
- 蒸气云爆炸冲击波uvce
- “十三五”重点项目-金属卡项目可行性研究报告 - 图文
- 休闲农业发展专项项目推荐汇总表 - 图文
- 小学对课
- 曲柄连杆机构故障诊断说课稿 - 图文
- 水结冰膨胀压力测试方法及实验数据分析
- 北京市西城区人民政府印发关于促进金融产业发展的意见
- 汽车构造
- RF工程师常用命令和参数介绍 - 图文
- 一起由于变压器励磁涌了引发的跳闸事件及处理办法 - 图文
- “与信仰对话,为青春导航”主题团日活动材料 - 图文
- 2012中国民营500强企业名单
- 精品2018最新版本高考物理二轮复习专题专题七-静电场教案-Word版