话说客户端发起请求, pg 服务器为该请求启动一个 postgres 访问进程为该客户端通过访问,建立了连接。这个 postgres 访问进程进入无限循环,等待客户端请求并为其通过服务,直到进程终止,连接断口。这节就看客户端向 postgres 服务进程发出请求的处理过程。
1
Postgres 服务进程处理请求的无限循环调用序列图
上图大红色方框中显示了 postgres 服务进程处理客户端访问的无限循环调用序列。我以一个简单的例子来展现处理简单查询的过程,就是走了上图中小红色方框中方法 execu_simple_query 。使用的例子如下:
先准备试验环境:创建数据库 TEST ,在里面创建表 TEST1 和 TEST2 。建这两个表的语句在下面。
create table test1 (ID numeric(10), cname varchar(30));
create table test2 (ID numeric(10), comp varchar(30));
试验内容就是在这两个表上做连接查询,查询语句如下:
select cname,comp from test1,test2 where test1.id=test2.id;
当客户端给服务器端发出查询 SQL 后,建立连接时已经启动且进入无限循环的服务器端的 postgres 服务进程处理步骤如下:
( 1 )调用 MemoryContextSwitchTo 切换内存上下文到 "MessageContext" 。
( 2 )调用 MemoryContextResetAndDeleteChildren 清理上次为相同连接服务时 "MessageContext" 内存上下文里遗留的对象。
( 3 )调用 ReadCommand 读取客户端的请求。
( 4 )根据客户端请求判断要提供何种服务,进入相应分支(参见《 pg 服务过程中的那些事一:启动 postgres 服务进程二:建立连接完成》)。根据例子里发的请求“ select cname,comp from test1,test2 where test1.id=test2.id ”进入简单查询分支处理方法 execu_simple_query 。
2
进入后的处理基本上涵盖了《数据库系统实现》这本书里的内容。处理量相当大,先根据流程图概览一下处理过程。为了减小图的大小,把 PostgresMain 以前的调用流程省略了。在以后的讨论中 PostgresMain 以前的调用流程也省略了,要回顾可以看上面的“ Postgres 服务进程处理请求的无限循环调用序列图”。
处理简单查询方法调用序列图
主要的处理过程是先调用 start_xact_command 方法 开启一个事务,再用 pg_parse_query 方法 用词法语法解析工具把查询命令解析为解析树 parsetree ,根据需要调用 PushActiveSnapshot 方法搞一个快照,调用 pg_analyze_and_rewrite 方法分析、根据规则重写解析树为查询树 querytree ,调用 pg_plan_queries 方法把查询树转换到执行计划树 plantree ,在调用相应方法创建 portal 和在 postal 中执行执行计划树并给客户端发回结果。然后退出当前事务,清理内存。
------------
转载请著明出处,来自博客:
blog.csdn.net/beiigang
beigang.iteye.com