postgresql源代码的组成
时间:2009-10-17 来源:fghler
这一篇短文中,将介绍postgresql源代码的组成。先感谢鼓励我做源代码分析的兄弟,呵呵,你们的鼓励也许将我推上了一条不归路。
从Linux下拷回通过编译的源代码后,在硬盘上展开,例如我展开后将所有的源代码放到D:\Postgresql\source目录下。然后建立一个目录D:\Postgresql\insight,打开sourceinsight后在这个目录下创建一个project,将D:\Postgresql\source\backend目录下的所有文件加入该项目
然后找到D:\Postgresql\source\doc\postgres.tar.gz,将它解开到D:\Posgresql\doc目录下,再用浏览器打开D:\Postgresql\doc\html\index.html并按ctrl+d加入收藏夹,有时间的话,最好先读完这份文档(这份文档有laser的中文翻译版)。另外再用浏览器打开D:\Postgresql\source\src\tools\backend\index.html,将它也加入收藏夹,这份文档的名称是"How PostgreSQL Processes a Query",随便点击文档中的图上任一框即转到postgresql源代码组成介绍,大致意思翻译如下:
PostgreSQL的Backend目录
作者:Bruce Momjian
--------------------------------------------------------------------------------
点击小节的标题即可见到该节的源代码
bootstrap - 通过initdb创建最初的数据库模板
几乎PostgreSQL的每一个操作都需要存取系统表,那么如何创建这些系统表呢?不能以通常的方式创建这些系统表并向其中插入数据,因为表的创建和插入要求系统表已经存在。这一部分代码的目的就是使用一种仅仅在bootstrap过程中使用的特殊方法来直接建立系统表
main - 将控制转到postmaster或postgres
检查进程名(argv[0])和各种标志, 然后将控制转到postmaster或postgres
postmaster - 控制postgres服务器启动/终止
创建共享内存,然后进入一个循环等待连接请求。当一个连接请求到达时,启动一个postgres后台服务进程,将连接转给它
libpq - 后台服务器libpq库函数
处理与客户进程间的通讯
tcop - 将请求分派到合适的模块
这是postgres后台服务进程的主要处理部分, 它调用parser, optimizer, executor, 和commands中的函数
parser - 将SQL查询转化为查询树
将来自libpq的SQL查询转换为命令形式的结构供optimizer/executor或commands使用.首先对SQL语句进行词法分析,转换为关键字,标识符和常量,然后进行语法分析。语法分析生成命令形式的结构来表示查询的组成。然后这个命令形式的结构被分离、检查和传送给commands中的处理函数,或者转换为结点链表供optimizer和executor处理
optimizer - 创建查询路径和查询计划
使用parser的输出来为executor生成优化了的查询计划.
optimizer/path - 使用parser的输出创建查询路径
它使用parser的输出生成所有可能的执行方法,它检查表的连接顺序,where子句限制和optimizer的表统计信息来评估每一个可能的执行方法,并赋予每个方法一个代价
optimizer/geqo - 遗传算法查询优化
optimizer/path对所有连接表的方法进行了评估。但是当表的数目变得很大时,检测测的数目也会变得很大。遗传算法查询优化对每一个表进行考虑,然后计算出最优的顺序来执行连接。如果只有几个表,这种方法花费较长的时间,但对于大量的表,这种方法就比较快了。系统有一个选项用于控制何时使用这个功能
optimizer/plan - 优化path输出
为optimizer/path的输出选择代价最小的路径并创建一个执行计划
optimizer/prep - 处理特殊的查询计划
对特殊的查询计划进行处理
optimizer/util - 优化器支持函数
供优化器其他部分使用的函数
executor - 执行来自optimizer的复杂的节点形式的查询计划
处理select, insert, update,和delete语句. 处理这些语句的操作包括堆扫描、索引扫描、排序、连接表、分组、计算集函数和唯一性处理
commands - 不需要executor执行的命令
执行不需要复杂处理的SQL命令.包括vacuum, copy, alter, create table, create type以及许多其他未能例举的命令。调用这一部分代码时使用由parser生成的结构.大多数的函数先做一些处理,然后就调用catalog目录下的一些低层函数来做实际的工作
catalog - 系统目录操作
包含用于操作系统表和系统目录的函数.表、索引、过程、运算符、类型、和集函数的创建和操纵函数在这里可以找到。它们都是低层的函数,通常由上层将用户请求格式化为预定义格式的函数调用
storage - 管理各种类型的存储系统
支持服务器以统一的方式存取资源
storage/buffer - 共享缓冲区管理
storage/file - 文件管理
storage/ipc - 信号灯和共享内存
storage/large_object - 大对象
storage/lmgr - 锁管理器
storage/page - 页管理器
storage/smgr - 存储/磁盘管理器
access - 各种存取方法
支持堆, 索引, 和事务对数据的存取
access/common - 公共存取函数
access/gist - 可自定义的存取方法
access/hash - hash
access/heap - 堆用于存取表
access/index - 所有索引类型都使用
access/nbtree - Lehman and Yao的btree管理算法
access/rtree - 用于索引2维数据
access/transam - 事务管理器(BEGIN/ABORT/COMMIT)
nodes - 创建/操纵节点和链表
PostgreSQL将SQL查询存储到称为节点的结构中。节点是通用的容器,它包含一个类型字段和一个与类型有关的数据字段.节点通常串成链表。
链表包含一个元素和一个next指针.节点和链表广泛的用于parser,optimizer,和executor中用于存储请求和数据
utils - 支持程序
utils/adt - 内建数据类型
包含所有PostgreSQL自带数据类型
utils/cache - system/relation/function高速缓存
PostgreSQL支持自定义数据类型,因此没有数据类型是固化在核心当中的。当服务器需要查找一个数据类型时它就到系统表中去找。由于系统表频繁使用,所以设立一个高速缓存来加速查找。系统中包括一个系统关系cache, 一个函数/运算符cache和一个关系信息cache. 关系信息cache中包含所有最近访问过的表的信息而不仅仅包含系统表的信息
utils/error - 错误报告
向前台报告后台错误
utils/fmgr - 函数管理器
处理动态加载函数的调用和在系统表中定义的函数的调用
utils/hash - 内部使用的hash程序
用于cache和内存管理器以便快速查找动态存储的数据结构
utils/init - 各种初始化
utils/misc - 未归类的东东
utils/mmgr - 内存管理器(进程私有内存)
PostgreSQL在显式的内存上下文中分配内存. 上下文可以是语句级、事务级或永久/全局级的.这样,后台服务器可以很容易地在一个语句或者事务结束的时候释放内存
utils/sort - 排序
在内存中或者使用磁盘文件排序
utils/time - 事务时间限定
检查元组是否仍然有效,还是属于未提交事务或者已被新行替代
include - 包含文件
每个子系统有一个目录
lib - 支持库
几个通用的程序
regex - 正规表达式库
用于后台服务器的正规表达式处理如'~'.
rewrite - 规则系统
完成规则系统的处理
tioga - 未用 (数组处理?)
--------------------------------------------------------------------------------
维护者: Bruce Momjian ([email protected])
最后更新于: Tue Dec 9 17:56:08 EST 1997
组成postgresql后台进程的源代码都在D:\Postgresql\source\src\backend目录下,上面这份文档中的小节标题就是子目录名称。面对着这份文档,该从哪里下手呢?我觉得所有服务器源代码大致可以分为四个组成部分:工具部分,查询处理部分,事务存储管理部分,系统初始化部分。工具部分基本集中于utils目录下,对于新手,可以由此入手感觉一下,例如分析分析mmgr的对外接口和内部实现算法。查询部分主要是tcop/rewrite/parser/optimizer/executor/commands等等。我打算从事务存储管理部分入手分析,主要的代码集中在storage/access之下。系统初始化部分最好到最后在分析。上面讲的还只是后台服务器,其他还有一些东东如odbc/jdbc、各种语言接口、管理工具如pgAdmin/pgAccess等等
接下来我要利用空闲时间读代码,估计要过一段时间(1-3个月?)才能再来和大家分享心得体会,热情希望和我有相同兴趣的兄弟也能利用自己工作之余的时间来做做源代码分析。
从Linux下拷回通过编译的源代码后,在硬盘上展开,例如我展开后将所有的源代码放到D:\Postgresql\source目录下。然后建立一个目录D:\Postgresql\insight,打开sourceinsight后在这个目录下创建一个project,将D:\Postgresql\source\backend目录下的所有文件加入该项目
然后找到D:\Postgresql\source\doc\postgres.tar.gz,将它解开到D:\Posgresql\doc目录下,再用浏览器打开D:\Postgresql\doc\html\index.html并按ctrl+d加入收藏夹,有时间的话,最好先读完这份文档(这份文档有laser的中文翻译版)。另外再用浏览器打开D:\Postgresql\source\src\tools\backend\index.html,将它也加入收藏夹,这份文档的名称是"How PostgreSQL Processes a Query",随便点击文档中的图上任一框即转到postgresql源代码组成介绍,大致意思翻译如下:
PostgreSQL的Backend目录
作者:Bruce Momjian
--------------------------------------------------------------------------------
点击小节的标题即可见到该节的源代码
bootstrap - 通过initdb创建最初的数据库模板
几乎PostgreSQL的每一个操作都需要存取系统表,那么如何创建这些系统表呢?不能以通常的方式创建这些系统表并向其中插入数据,因为表的创建和插入要求系统表已经存在。这一部分代码的目的就是使用一种仅仅在bootstrap过程中使用的特殊方法来直接建立系统表
main - 将控制转到postmaster或postgres
检查进程名(argv[0])和各种标志, 然后将控制转到postmaster或postgres
postmaster - 控制postgres服务器启动/终止
创建共享内存,然后进入一个循环等待连接请求。当一个连接请求到达时,启动一个postgres后台服务进程,将连接转给它
libpq - 后台服务器libpq库函数
处理与客户进程间的通讯
tcop - 将请求分派到合适的模块
这是postgres后台服务进程的主要处理部分, 它调用parser, optimizer, executor, 和commands中的函数
parser - 将SQL查询转化为查询树
将来自libpq的SQL查询转换为命令形式的结构供optimizer/executor或commands使用.首先对SQL语句进行词法分析,转换为关键字,标识符和常量,然后进行语法分析。语法分析生成命令形式的结构来表示查询的组成。然后这个命令形式的结构被分离、检查和传送给commands中的处理函数,或者转换为结点链表供optimizer和executor处理
optimizer - 创建查询路径和查询计划
使用parser的输出来为executor生成优化了的查询计划.
optimizer/path - 使用parser的输出创建查询路径
它使用parser的输出生成所有可能的执行方法,它检查表的连接顺序,where子句限制和optimizer的表统计信息来评估每一个可能的执行方法,并赋予每个方法一个代价
optimizer/geqo - 遗传算法查询优化
optimizer/path对所有连接表的方法进行了评估。但是当表的数目变得很大时,检测测的数目也会变得很大。遗传算法查询优化对每一个表进行考虑,然后计算出最优的顺序来执行连接。如果只有几个表,这种方法花费较长的时间,但对于大量的表,这种方法就比较快了。系统有一个选项用于控制何时使用这个功能
optimizer/plan - 优化path输出
为optimizer/path的输出选择代价最小的路径并创建一个执行计划
optimizer/prep - 处理特殊的查询计划
对特殊的查询计划进行处理
optimizer/util - 优化器支持函数
供优化器其他部分使用的函数
executor - 执行来自optimizer的复杂的节点形式的查询计划
处理select, insert, update,和delete语句. 处理这些语句的操作包括堆扫描、索引扫描、排序、连接表、分组、计算集函数和唯一性处理
commands - 不需要executor执行的命令
执行不需要复杂处理的SQL命令.包括vacuum, copy, alter, create table, create type以及许多其他未能例举的命令。调用这一部分代码时使用由parser生成的结构.大多数的函数先做一些处理,然后就调用catalog目录下的一些低层函数来做实际的工作
catalog - 系统目录操作
包含用于操作系统表和系统目录的函数.表、索引、过程、运算符、类型、和集函数的创建和操纵函数在这里可以找到。它们都是低层的函数,通常由上层将用户请求格式化为预定义格式的函数调用
storage - 管理各种类型的存储系统
支持服务器以统一的方式存取资源
storage/buffer - 共享缓冲区管理
storage/file - 文件管理
storage/ipc - 信号灯和共享内存
storage/large_object - 大对象
storage/lmgr - 锁管理器
storage/page - 页管理器
storage/smgr - 存储/磁盘管理器
access - 各种存取方法
支持堆, 索引, 和事务对数据的存取
access/common - 公共存取函数
access/gist - 可自定义的存取方法
access/hash - hash
access/heap - 堆用于存取表
access/index - 所有索引类型都使用
access/nbtree - Lehman and Yao的btree管理算法
access/rtree - 用于索引2维数据
access/transam - 事务管理器(BEGIN/ABORT/COMMIT)
nodes - 创建/操纵节点和链表
PostgreSQL将SQL查询存储到称为节点的结构中。节点是通用的容器,它包含一个类型字段和一个与类型有关的数据字段.节点通常串成链表。
链表包含一个元素和一个next指针.节点和链表广泛的用于parser,optimizer,和executor中用于存储请求和数据
utils - 支持程序
utils/adt - 内建数据类型
包含所有PostgreSQL自带数据类型
utils/cache - system/relation/function高速缓存
PostgreSQL支持自定义数据类型,因此没有数据类型是固化在核心当中的。当服务器需要查找一个数据类型时它就到系统表中去找。由于系统表频繁使用,所以设立一个高速缓存来加速查找。系统中包括一个系统关系cache, 一个函数/运算符cache和一个关系信息cache. 关系信息cache中包含所有最近访问过的表的信息而不仅仅包含系统表的信息
utils/error - 错误报告
向前台报告后台错误
utils/fmgr - 函数管理器
处理动态加载函数的调用和在系统表中定义的函数的调用
utils/hash - 内部使用的hash程序
用于cache和内存管理器以便快速查找动态存储的数据结构
utils/init - 各种初始化
utils/misc - 未归类的东东
utils/mmgr - 内存管理器(进程私有内存)
PostgreSQL在显式的内存上下文中分配内存. 上下文可以是语句级、事务级或永久/全局级的.这样,后台服务器可以很容易地在一个语句或者事务结束的时候释放内存
utils/sort - 排序
在内存中或者使用磁盘文件排序
utils/time - 事务时间限定
检查元组是否仍然有效,还是属于未提交事务或者已被新行替代
include - 包含文件
每个子系统有一个目录
lib - 支持库
几个通用的程序
regex - 正规表达式库
用于后台服务器的正规表达式处理如'~'.
rewrite - 规则系统
完成规则系统的处理
tioga - 未用 (数组处理?)
--------------------------------------------------------------------------------
维护者: Bruce Momjian ([email protected])
最后更新于: Tue Dec 9 17:56:08 EST 1997
组成postgresql后台进程的源代码都在D:\Postgresql\source\src\backend目录下,上面这份文档中的小节标题就是子目录名称。面对着这份文档,该从哪里下手呢?我觉得所有服务器源代码大致可以分为四个组成部分:工具部分,查询处理部分,事务存储管理部分,系统初始化部分。工具部分基本集中于utils目录下,对于新手,可以由此入手感觉一下,例如分析分析mmgr的对外接口和内部实现算法。查询部分主要是tcop/rewrite/parser/optimizer/executor/commands等等。我打算从事务存储管理部分入手分析,主要的代码集中在storage/access之下。系统初始化部分最好到最后在分析。上面讲的还只是后台服务器,其他还有一些东东如odbc/jdbc、各种语言接口、管理工具如pgAdmin/pgAccess等等
接下来我要利用空闲时间读代码,估计要过一段时间(1-3个月?)才能再来和大家分享心得体会,热情希望和我有相同兴趣的兄弟也能利用自己工作之余的时间来做做源代码分析。
相关阅读 更多 +