2.4.7 循环等待客户连接请求

PostgreSQL系统采用客户端/服务器模式(C/S),系统为每个客户端分配一个后台服务进程Postgres。一次PostgreSQL会话由下列相关的进程(程序)组成:

服务进程叫Postgres,它接受来自客户端应用与数据库的连接,并且代表客户端在数据库上执行操作。

客户端进程,是指运行在客户端与Postmaster或Postgres进程交互的进程,比如在客户端运行的psql进程。

和典型的C/S应用一样,这些客户端和服务器可以在不同的主机上。这时它们通过网络连接通信。当客户端欲访问某一数据库时,就调用接口库(比如libpq、ODBC)把用户的请求通过网络连接发给守护进程Postmaster。Postmaster将启动一个新的服务进程Postgres为用户服务,此后客户端进程和服务进程不再通过Postmaster而是直接进行通信。Postmaster总是监听用户连接请求并为用户分配服务进程Postgres,而Postgres则负责为客户端执行各种命令。从第3章开始将对它们的实现机制进行详细介绍。

在完成前述工作之后,Postmaster将调用ServerLoop函数来循环等待客户端的连接请求,该函数的主体是一个死循环,它的主要功能就是在监听到用户的连接请求后建立与该用户的连接,然后通过调用fork函数复制出一个Postgres进程为该用户服务。

在ServerLoop函数中,首先调用initMasks函数初始化Postmaster所关心的读文件描述符集(通过扫描ListenSocket数组将里面的监听套接口字描述符加入到读文件描述符集中)。

接下来进入到一个死循环中,循环中首先调用select系统函数等待客户端提出连接请求。当select函数正常返回后,扫描ListenSocket数组,检查数组中的每一个监听套接字描述符,如果发现该套接字上有用户提出连接请求,那么将调用ConnCreate函数来创建一个Port结构体。该函数首先从CurrentMemoryContext中创建一个Port结构体,然后调用Accept系统函数接受由该监听套接字所维护的用户连接请求队列中的第一个连接请求,将监听套接字转化成一个已连接的套接字,并将返回的已连接套接字和用户端套接口地址结构都填入到Port的相应属性中。对于TCP连接,还要为连接设置超时等连接选项。Port结构的部分定义如数据结构2.7所示。

成功创建Port结构体之后,调用BackendStartup启动后台进程接替Postmaster与用户进行连接,然后Postmaster关闭

数据结构2.7 Port

    typedef struct Port  
    {  
    int      sock;            //已连接的套接口字描述符  
    SockAddrladdr;//服务器端的地址信息  
    SockAddrraddr;//客户端的地址信息  
    char*database_name;//要连接的数据库名  
    char*user_name;//连接的用户名  
    ……  
    }Port;

与用户的连接,释放Port结构体,检查并确保辅助进程如BgWriter、SysLogger等正常运行,完成之后就进入下一次循环,继续等待用户连接请求的到来。

BackendStartup函数将根据Port结构体来启动一个Postgres服务进程,为用户提供服务。函数首先调用PostmasterRandom函数为即将创建的子进程生成一个随机数,并分配一个Backend结构。然后调用fork函数复制出一个Postgres子进程。

在子进程中将首先调用BackendInitialize函数获取用户端的相关信息(客户端的主机名、端口、用户名、数据库名等),然后将相关数据填入到Port结构中,再通过ClientAuthentication函数进行用户认证,检查用户端的地址、要连接的数据库、使用的用户名在pg_hba.conf文件中是否被允许,并根据pg_hba.conf中设置的认证方法与客户端进行相应的交互(见8.2节)。接下来该子进程将调用BackendRun来设置Postgres运行时的命令行参数,并且进行一些初始化工作,最后将调用PostgresMain函数进入Postgres的执行入口。

而在父进程也就是Postmaster中,会将随机数和子进程pid填入到Backend结构中,然后将该结构体加入到Postmaster维护的BackendList链表中。这样,Postmaster才能通过BackendList链表来监控其子进程。

在ServerLoop循环中,除等待用户连接请求建立Postgres服务进程外,将检查辅助进程的状态,并根据需要启动辅助进程。

Postmaster在数据库中扮演着管理员的角色,为用户的请求准备一个干净的环境。用户发送一个开始消息,Postmaster即可根据该消息建立一个后端Postgres服务进程处理用户的操作,之后用户直接与Postgres进程通信而无需通过Postmaster中转。Postmaster则继续监听新用户的请求。在整个数据库的生存周期中,Postmaster都只执行管理工作,通过派生出各种辅助进程来执行相关功能,这个分离的结构极大地增强了系统的容错恢复特性。

【责任编辑:云霞 TEL:(010)68476606】

results matching ""

    No results matching ""