转载:PostgreSQL内核分析 (1)

前端之家收集整理的这篇文章主要介绍了转载:PostgreSQL内核分析 (1)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载:http://bbs.chinaunix.net/thread-1805302-1-1.html

Postgresql内核分析
闫华 postgres_fan@yahoo.com.cn
1前言
一直都想写关于Postgresql实现原理方面的文章,由于这是一个工作量巨大的工作,平时还要工作谋生,很难抽出时间来写,希望能够坚持下来。Postgresql作为历史最悠久的开源数据库管理系统,有关它的详细信息可以到http://www.postgresql.org/去查阅,这里不再赘述。在MysqL被Oracle抓在手中以后,MysqL变得前途未卜,在这种情况下,Postgresql显得越发地重要。
Postgresql作为脱胎于学术研究的数据库管理系统,源代码结构非常地清晰,易于理解,相比之下,MysqL代码结构就要乱很多(个人之见,MysqL的粉丝不要喷我)。
Postgresql的源代码的规模已经非常地大,文件众多。初学者如果直接去看代码,必然如坠五里雾中,难以理解,所以我的文章着重讲述源代码背后的实现原理,而不是详细地叙述每个函数的输入输出以及每一行代码的作用。让读者能从宏观上把握系统结构,循着系统的主线去阅读源代码要容易地多。
这将是一系列的连载文章,闲言少叙,让我们先从Postgresql的进程结构说起。

2 Postgresql进程结构
Postgresql与Oracle类似,是多进程结构的数据库。在Postgresql中主要有postmaster,postgres,vacuum,bgwriter,pgarch,walwriter,pgstat等进程,下面先简单介绍一下每个进程的作用,然后再详细介绍每个进程的实现原理。

(1)postmaster
负责在启动数据库的时候创建共享内存并初始化各种内部数据结构,如锁表,数据库缓冲区等,该进程在数据库中只有一个。在数据库启动以后负责监听用户请求,创建postgres进程来为用户服务。这一点与Oracle的TNS listener进程类似。

(2)postgres
负责执行用户发出的所有sql语句,该进程在数据库中可能有多个,Oracle中叫shadow process。

(3)vacuum
负责清除数据库中无用的历史数据(已经被删除或更新的记录)。更新优化器的统计信息,确保产生可以接受的查询计划,该进程在数据库可能有多个,Oracle无此种类型进程。

(4)bgwriter
负责将数据缓冲区中已被更新的数据库写入数据库物理数据文件中,Oracle中对应的进程叫DBWR,该进程在数据库中只有一个。

(5)pgarch
负责将系统产生的redo log复制到其他外部存储介质中, Oracle中对应的进程叫Archiver,该进程在数据库中只有一个。

(6)walwriter
负责将系统产生的redo log 写到redo log 文件中(在pg_xlog目录下),Oracle中对应的进程叫LGWR,该进程在数据库中只有一个。

(7)pgstat
负责收集数据库运行中的统计信息,如一个表上面进行了多少次插入与更新操作,该进程在数据库中只有一个,Oracle无此种类型进程。

2.1 Postmaster进程
Postmaster进程是Postgresql启动以后创建的第一个进程,所有的其他进程都是由Postmaster创建的。与Postmaster进程相关的大部分代码都在src\backend\postmaster\postmaster.c文件中。Postmaster进程的入口函数是PostmasterMain。
Postmaster进程在系统启动时首先进行一些初始化工作,创建共享内存和信号量等数据结构,创建pgstat等后台进程,然后调用ServerLoop函数进入监听客户端连接请求的状态,ServerLoop函数代码是一个无限循环的结构,正常的情况下,Postmaster进程永远都不会退出ServerLoop函数。ServerLoop函数的主要功能是在收到客户端连接请求的情况下,创建一个新的postgres进程来为客户端服务。
因为所有的其他进程都由Postmaster进程创建,所以它们都是Postmaster的子进程。当一个postgres、bgwriter、 walwriter或vacuum进程因为非正常原因崩溃以后,Postmaster进程要进行一些清理工作,释放它们占用的内部资源,或者重新启动这些进程。postmaster.c中的reaper函数就是负责执行这个任务的。

2.2 Postgres进程
Postgres进程负责执行客户端发出的所有的sql语句及自定义函数。与Postgres进程相关的代码在src/backend/tcop/postgres.c文件中,Postgres进程的入口函数是PostgresMain。
PostgresMain首先进行一些初始化工作,然后使用语句for (;进入一个无限循环状态,等待客户端发来命令请求,接受客户端命令,执行客户端命令,将执行结果返回给客户端。
for (;无限循环体首先调用ReadCommand从客户端读取一条命令,然后根据命令类型,调用相应的处理函数。例如,对于可以直接执行的sql语句(simple query),命令类型的代码是“Q”,处理代码如下:
case 'Q': /* simple query */
{
const char *query_string;

/* Set statement_timestamp() */
SetCurrentStatementStartTimestamp();

query_string = pq_getmsgstring(&input_message);
pq_getmsgend(&input_message);

exec_simple_query(query_string);

send_ready_for_query = true;
语句exec_simple_query(query_string)负责解析sql语句,生成查询计划,执行查询计划,将查询结果返回给客户端。

2.3 Vacuum进程
Postgresql使用的是多版本的并发控制机制,历史数据与当前数据都存放在同一个数据库中,当某些历史数据不再有用时,应当把这些历史数据从数据库删除掉(这个过程叫vacuum),让这些数据所占的存储空间能够被重新利用,否则数据库所占的存储空间会越来越大,最后会消耗掉所有的物理存储空间,导致数据库无法继续正常运行。Vacuum进程负责清除无用的历史数据
Vacuum进程分两种。第一种叫Vacuum控制进程,第二种Vacuum工作进程。自动垃圾Vacuum控制进程在数据库中只有一个,数据库启动以后这个进程就存在,它睡眠一段时间后,就创建一个或多个Vacuum工作进程来进行垃圾收集(Vacuum控制进程不直接创建Vacuum工作进程,而是通过postmaster进程创建Vacuum工作进程),然后再进入睡眠状态,不断地重复这个循环,每次睡眠的时间由参数autovacuum_naptime指定。Vacuum工作进程负责真正的垃圾收集工作,参数autovacuum_max_workers控制能够被同时创建的Vacuum工作进程的个数的最大值。
与Vacuum控制进程相关的大部分代码都在backend/postmaster/autovacuum.c文件中,Vacuum控制进程的入口函数是AutoVacLauncherMain。AutoVacLauncherMain首先进行一些初始化工作,然后使用语句for (;进入一个无限循环状态,睡眠一端时间,检查是否需要创建新的Vacuum工作进程,如果需要,通知Postmaser创建新的Vacuum工作进程,然后继续睡眠,不断地重复这个过程。
原文链接:https://www.f2er.com/postgresql/196140.html

猜你在找的Postgre SQL相关文章