资讯专栏INFORMATION COLUMN

PostgreSQL逻辑和物理结构

IT那活儿 / 2140人阅读
PostgreSQL逻辑和物理结构

点击上方“IT那活儿”,关注后了解更多内容,不管IT什么活儿,干就完了!!!





文章前言



在了解PostgreSQL逻辑和物理结构之前,我们先了解PostgreSQL的系统架构,PostgreSQL使用一种客户端/服务器的模型。
其会话由下列相关的进程或程序组成:
一个服务器进程,它管理数据库文件、接受来自客户端应用与数据库的连接并且在数据库上执行操作,该进程叫做postgres。
那些需要执行数据库操作的用户的客户端应用。
客户端应用可能本身就是多种多样的:
可以是一个面向文本的工具,也可以是一个图形界面的应用,或者是一个通过访问数据库来显示网页的网页服务器,或者是一个特制的数据库管理工具。例如PoWA,pgAdmin等。
PostgreSQL采取类似于Oracle的多进程模式,在服务器处理来自客户端的多个并发请求时,它会为每个连接fork一个新的进程。从这个时候开始,客户端和新服务器进程就不再经过 postgres进程的进行通信。
因此,主服务器进程总是在运行并等待着客户端的连接,而新派生的进程就负责处理客户端的各种操作。





PostgreSQL的逻辑结构



Database cluster: 
数据库集群,或者叫数据库实例,由PostgreSQL server管理的数据库的集合,由多个database组成。每个正在运行的PostgreSQL server实例都管理着一个或多个数据库。
database:
由各种数据库对象构成,例如table,indexes, view,function,sequence等。在数据库对象的层次结构中,database位于最顶层。通常每个数据库对象(table、function等) 属于并且只属于一个database,但是也有几个系统表例如pg_database属于整个数据库集群,对于集群中的每个database来说都是可访问的)。

图 1  PostgreSQL的逻辑结构
PostgreSQL中的所有数据库对象都通过对象标识符oid(object identifiers), oid是无符号的四字节整数,数据库对象的oid存放在相关的system catalog表中,且数据库对象与oid的关系取决于对象的类型,例如,数据库和表的oid分别存放在pg_database,pg_class表中,通过下面的查询语句可以找到指定对象的oid。
示例:
查看数据库pgtest的oid:
查看表products的oid:
当我们执行initdb命令初始化PostgreSQL时,默认就创建了template0、 template1和postgres这3个数据库。
template0和template1数据库是创建用户数据库时将要用到的模版数据库,它们包含了系统的元数据表。
initdb刚完成时,template0和template1数据库中的表是一样的,设置两个模版数据库的原因是template0是初始状态,template1则可以集成用户的某些需求。用户数据库是通过克隆template1来创建的。postgres数据库是使用模版template1创建的默认数据库,如果连接时不指定数据库名,则默认连接到postgres数据库。
查看数据库集群当前有哪些数据库:
上图中,pgtest是初始化完成之后用户新创建的一个数据库。
通过datistemplate列可知template0和template1是用户创建数据库时使用的模版数据库,其他的则不是模版数据库。
通过datlowconn列可知该数据库是否允许访问。template0数据库不能被访问,因此该数据库不能被修改。
tablespace:
PostgreSQL的表空间的概念与其他关系数据库有所不同,在PostgreSQL中,一个表空间对应的是一个目录,里面存放的是数据目录之外的一些数据,一般是业务数据。
当我们初始化PostgreSQL后,就默认创建了pg_default和pg_global这两个表空间。
建表时如果没有指定特定的表空间,表默认存储在pg_default表空间中。pg_global表空间中默认存储的是用于管理整个数据库集群的表。
block:
在PostgreSQL中,将保存在磁盘中的块称为Page,而将内存中的块称为Buffer,表和索引称为Relation,行称为Tuple。数据的读写是以Page为最小单位,每个Page默认大小为8KB,页的尺寸可以在编译PostgreSQL时指定。





PostgreSQL的物理结构



当我们初始化一个新的数据库集群的时候,会在指定目录下创建一个数据目录,这个数据目录的路径通常用环境变量$PGDATA来表示,初始化完成后,会在$PGDATA下生成相关的子目录以及文件。
1. 数据库的物理结构
图2展示了PostgreSQL数据库集群的物理结构。database是$PGDATA/base路径下的子目录,每个表和索引(至少)是一个文件,存储在它所属的数据库(例如testdb)的子目录下。另外,还有几个包含特定数据和配置文件的子目录。
图2  PostgreSQL的物理结构
下面是数据目录下的文件和子目录的信息:
相关文件和子目录的介绍如下:


如下图所示,每个数据库的oid都对应了$PGDATA/base路径下面的一个子目录:
2. 表空间的物理结构
PostgreSQL初始化时默认创建pg_default和pg_global这两个表空间,pg_default表空间的物理位置为$PGDATAase目录,pg_global表空间的物理位置为$PGDATAglobal目录。用户新建的表空间对应的目录都位于pg_tblspc下。
一个表空间可以同时被多个数据库使用,这时,每个数据库都会在表空间的路径下创建一个新的子路径。
每创建一个用户表空间就会在$PGDATApg_tblspc目录下面创建一个软链接,连接到表空间指定的目录位置。
例如,当我们创建一个名为tbs_test表空间,路径是/home/postgres/data2/tbs_test,那么就会在pg_tblspc目录下面生成一个软连接的目录16425,这里的16425就是表空间对应的oid,再往下可以看到子目录16384,对应的是database的oid。
3. 表和索引的物理结构
表或者索引超过 1GB 之后,它就被划分成1G大小的segment。第一个segment的文件名和文件节点相同;随后的segment被命名为 filenode.1、filenode.2等等。
这样的安排避免了在某些有文件大小限制的平台上的问题(实际上,1GB只是默认的segment尺寸。segment尺寸限制可以在编译PostgreSQL时使用配置选项--with-segsize进行调整)。
如下:
cd $PGDATA
$ ls -la -h base/16384/19427*
-rw------- 1 postgres postgres 1.0G Aug 6 10:33 data/base/16384/19427
-rw------- 1 postgres postgres 45M Aug 6 10:33 data/base/16384/19427.1





本文作者:魏 斌

本文来源:IT那活儿(上海新炬王翦团队)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/129590.html

相关文章

  • 新书推荐 |《PostgreSQL实战》出版(提供样章下载)

    摘要:作者谭峰张文升出版日期年月页数页定价元本书特色中国开源软件推进联盟分会特聘专家撰写,国内多位开源数据库专家鼎力推荐。张文升中国开源软件推进联盟分会核心成员之一。 很高兴《PostgreSQL实战》一书终于出版,本书大体上系统总结了笔者 PostgreSQL DBA 职业生涯的经验总结,本书的另一位作者张文升拥有丰富的PostgreSQL运维经验,目前就职于探探科技任首席PostgreS...

    Martin91 评论0 收藏0
  • 大佬为你揭秘微信支付的系统架构,你想知道的都在这里了

    摘要:年之前,微信支付业务快速发展,需要一款数据库能够安全高效的支撑微信支付商户系统核心业务,这个重任落在了腾讯数据库团队自研上。由于是用于微信支付的核心数据库,腾讯被定位为安全高效,稳定,可靠的数据库集群。 欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由李跃森发表于云+社区专栏李跃森,腾讯云PostgreSQL首席架构师,腾讯数据库团队架构师,负责微信支付商户系统核心数...

    Terry_Tai 评论0 收藏0
  • 让 TiDB 访问多种数据源 | TiDB Hackathon 优秀项目分享

    摘要:拿到返回结果进一步的进行计算处理。比较痛苦的经历不支持,我们就只好写内置函数,就把另外一个模块拖下来,自己修改加上语法,然后在加上自己设计的内置函数。其次就是涉及的的源码模块很多,从优化器执行器内置函数以及各种各样的结构。 本文作者是来自 CC 组的兰海同学,他们的项目《让 TiDB 访问多种数据源》在本届 TiDB Hackathon 2018 中获得了二等奖。该项目可以让 TiDB...

    OBKoro1 评论0 收藏0
  • 让 TiDB 访问多种数据源 | TiDB Hackathon 优秀项目分享

    摘要:拿到返回结果进一步的进行计算处理。比较痛苦的经历不支持,我们就只好写内置函数,就把另外一个模块拖下来,自己修改加上语法,然后在加上自己设计的内置函数。其次就是涉及的的源码模块很多,从优化器执行器内置函数以及各种各样的结构。 本文作者是来自 CC 组的兰海同学,他们的项目《让 TiDB 访问多种数据源》在本届 TiDB Hackathon 2018 中获得了二等奖。该项目可以让 TiDB...

    JasonZhang 评论0 收藏0

发表评论

0条评论

IT那活儿

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<