?????????
参考:http://book.51cto.com/art/201201/313175.htm
体系架构
PostgreSQL数据库由连接管理系统(系统控制器)、编译执行系统、存储管理系统、事务系统、系统表五大部分组成,其组成结构和关系如图2-1所示。
连接管理系统接受外部操作对系统的请求,对操作请求进行预处理和分发,起系统逻辑控制作用;
编译执行系统由查询编译器、查询执行器组成,完成操作请求在数据库中的分析处理和转化工作,最终实现物理存储介质中数据的操作;
存储管理系统由索引管理器、内存管理器、外存管理器组成,负责存储和管理物理数据,提供对编译查询系统的支持;
事务系统由事务管理器、日志管理器、并发控制、锁管理器组成,日志管理器和事务管理器完成对操作请求处理的事务一致性支持,锁管理器和并发控制提供对并发访问数据的一致性支持;
系统表是PostgreSQL数据库的元信息管理中心,包括数据库对象信息和数据库管理控制信息。系统表管理元数据信息,将PostgreSQL数据库的各个模块有机地连接在一起,形成一个高效的数据管理系统。
数据库初始化(initdb)过程
???? 执行initdb程序时,将从initdb.c文件中的main函数开始执行,main函数的执行流程如图2-3所示。initdb执行时将按照顺序执行下列工作:
1)根据用户输入的命令行参数获取输入的命令名。
2)设置系统编码为LC_ALL,查找执行命令的绝对路径并设置该路径。
3)设置环境变量(pg_data等),获取系统配置文件的源文件路径(postgres.bki、postgresql.conf.sample等文件),并检查该路径下各文件的可用性。
4)设置中断信号处理函数,对终端命令行SIGHUP、程序中断SIGINT、程序退出SIGQUIT、软件中断SIGTERM和管道中断SIGPIPE等信号进行屏蔽,保证初始化工作顺利进行。
5)创建数据目录,以及该目录下一些必要的子目录,如base、global、base/1等。
6)测试当前服务器系统性能,由测试结果创建配置文件postgresql.conf、pg_hba.conf、pg_ident.conf,并对其中定义的参数做一些设置。
7)在bootstrap模式下创建数据库template1,存储在数据目录的子目录base/1/中。
8)创建系统视图、系统表TOAST表等,复制template1来创建template0和postgres,这些操作都用普通的SQL命令来完成。
9)打印操作成功等相关信息,退出。
initdb是PostgreSQL中一个独立的程序,它的主要工作就是对数据集簇进行初始化,创建模板数据库和系统表,并向系统表中插入初始元组。在这以后,用户创建各种数据库、表、视图、索引等数据库对象和进行其他操作时,都是在模板数据库和系统表的基础上进行的。????
数据库集簇
PostgreSQL安装完成后,在做任何其他事情之前,必须先使用initdb程序初始化磁盘上的数据存储区,即数据集簇,由PostgreSQL管理的用户数据库以及系统数据库总称为数据集簇。在PostgreSQL的实现中,数据库就是磁盘上一些文件的集合,只不过这些文件有特定的文件名、存储位置等,并且有些文件之间会相互关联。默认情况下,PostgreSQL的所有数据都存储在其数据目录里,这个数据目录通常会用环境变量PGDATA来引用,后文中将会用PGDATA来指代数据目录。
在PostgreSQL中,对象标识符(OID)用来在整个数据集簇中唯一地标识一个数据库对象,这个对象可以是数据库、表、索引、视图、元组、类型等。PostgreSQL提供了Oid数据类型来表示OID,它实际上是一个无符号整数。
OID——对象标识符
OID通常是从1开始分配,但在初始化数据集簇时,会先将一部分OID分配给系统表、系统表元组、系统表上的索引等数据库对象,这一部分OID可以在系统表所对应的头文件中找到。同时,为了给后续版本留下扩展的余地,初始化数据集簇时还会预留一部分OID资源。这样,在系统运行时可分配的OID资源实际是从16384开始的。在PostgreSQL源代码src/include/catalog子目录下有一个shell脚本unused_oids用来输出当前版本中预分配和预留的OID的使用情况。
系统数据库
在创建数据集簇之后,该集簇中默认包含三个系统数据库template1、template0和postgres。其中template0和postgres都是在初始化过程中从template1拷贝而来的。
template1和template0数据库用于创建数据库。PostgreSQL中采用从模板数据库复制的方式来创建新的数据库,在创建数据库的命令中可以用“-T”选项来指定以哪个数据库为模板来创建新数据库。
template1数据库是创建数据库命令默认的模板,也就是说通过不带“-T”选项的命令创建的用户数据库是和template1一模一样的。template1是可以修改的,如果对template1进行了修改,那么在修改之后创建的用户数据库中也能体现出这些修改的结果。template1的存在允许用户可以制作一个自定义的模板数据库,在其中用户可以创建一些应用需要的表、数据、索引等,在日后需要多次创建相同内容的数据库时,都可以用template1作为模板生成。
由于template1的内容有可能被用户修改,因此为了满足用户创建一个“干净”数据库的需求,PostgreSQL提供了template0数据库作为最初始的备份数据,当需要时可以用template0作为模板生成“干净”的数据库。
而第三个初始数据库postgres用于给初始用户提供一个可连接的数据库,就像Linux系统中一个用户的主目录一样。
上述系统数据库都是可以删除的,但是两个模板数据库在删除之前必须将其在pg_database中元组的datistemplate属性改为FALSE,否则删除时会提示“不能删除一个模板数据库”。
系统表、视图
在关系数据库中,为了实现数据库系统的控制,必须提供数据字典的功能。数据字典不仅存储各种对象的描述信息,而且存储系统管理所需的各种对象的细节信息。从内容来看,数据字典包含数据库系统中所有对象及其属性的描述信息、对象之间关系的描述信息、对象属性的自然语言含义以及数据字典变化的历史(即数据库的状态信息)。数据字典是关系数据库系统管理控制信息的核心,在PostgreSQL数据库系统中,系统表扮演着数据字典的角色。
系统表是PostgreSQL数据库存放结构元数据的地方,它在PostgreSQL中表现为存放有系统信息的普通表或者视图。用户可以删除然后重建这些表、增加列、插入和更新数值,然而由用户去修改系统会导致系统信息的不一致性,进而导致系统控制紊乱。正常情况下不应该由用户手工修改系统表,而是由SQL命令关联的系统表操作自动维护系统表信息。比如,创建数据库语句(CREATE DATABASE)会向pg_database系统表插入一行,并且在磁盘上创建该数据库。
PostgreSQL的每一个数据库中都有自己的一套系统表,其中大多数系统表都是在数据库创建时从模板数据库中拷贝过来的,因此这些系统表里的数据都是与所属数据库相关的。只有少数系统表是所有数据库共享的(比如pg_database),这些系统表里的数据是关于所有数据库的。
由于系统表保存了数据库的所有元数据,所以系统运行时对系统表的访问是非常频繁的。为了提高系统性能,在内存中建立了共享的系统表CACHE,使用Hash函数和Hash表提高查询效率,这些内容将在第3章详细介绍。
进程结构
PostgreSQL系统的主要功能都集中于Postgres程序,其中的各个进程都是通过载入Postgres程序而形成的进程,只是在运行时所处的分支不同而已。PostgreSQL使用一种专用服务器进程体系结构,主要进程有:
Postgres程序的入口就是main模块的main函数。
守护进程postmaster(单用户模式下的Postgres进程):
完成数据集簇初始化后,用户可以启动一个数据库实例来运行数据库管理系统,多用户模式下一个数据库实例由数据库服务器守护进程Postmaster来管理。主要功能:
1.它是一个运行在服务器上的总控进程,负责整个系统的启动和关闭,并且在服务进程出现错误时完成系统的恢复。
2.它管理数据库文件、监听并接受来自客户端(psql,jdbc等)的连接请求,并且为客户端连接请求fork一个Postgres服务进程,来代表客户端在数据库上执行各种命令。
3.同时Postmaster还管理与数据库运行相关的辅助进程。用户可以使用postmaster、postgres或者pg_ctl命令启动Postmaster。
PostgreSQL采用C/S模式,系统为每个客户端分配一个服务进程。Postmaster就像一个处理客户端请求的调度中心。前端应用欲访问某一数据库时,就调用接口库(比如ODBC、libpq)把用户的请求通过网络发给守护进程Postmaster。Postmaster将启动一个新的服务进程Postgres为用户服务,此后前端进程和服务进程不再通过Postmaster而是直接进行通信。
服务进程Postgres:
服务进程Postgres接受并执行客户端(比如psql,或用户应用程序通过JDBC等接口)发送的命令(交互式SQL查询)。它在底层模块(如存储、事务管理、索引等)之上调用各个主要的功能模块(如编译器、优化器、执行器等),完成客户端的各种数据库操作,并返回执行结果。
客户端每创建一个数据库连接,postmaster生成一个postgres服务器进程,直接接受用户的命令进行编译执行,并将结果返回给用户。如此循环,直到用户断开连接。 服务器进程通过信号量和共享内存来相互通信。
辅助进程(分别为实现不同功能):
系统日志进程SysLogger :
后台写进程bgWriter:
预写式日志写进程WalWriter:
预写式日志归档进程pg_archive:
系统自动清理进程AutoVacuum:将自动定时整理(清理)外存中的数据空间。
统计数据收集进程pg_state:将自动统计系统运行中的一些动态信息。
????????