对 pcp_pool_status的分析

Pgpool-II带了很多的 pcp命令,据说有一个 什么 management server;

所以就想研究一下。

当初用 pg_md5命令:pg_md5 postgres 得到一个乱七八糟的字符串:

e8a48653851e28c69d0506508fb27fc5

拷贝到了 pcp.conf 最后一行:

postgres:e8a48653851e28c69d0506508fb27fc5

启动pgpool以后,再开另外一个终端:

pcp_pool_status  -d 10 localhost postgres postgres ,会报告一堆各个后台数据库节点的信息。

pcp_pool_status是一个独立的客户端程序。在pgpool中对它进行相应的是谁呢:

初步分析,是 pcp_child.c 中的 pcp_do_accept 函数(它在 pcp_do_child的循环中运行)

经过运行验证,果真如此:

static PCP_CONNECTION *                                    
pcp_do_accept(int unix_fd, int inet_fd){                                    
    PCP_CONNECTION *pc = NULL;     
    fd_set readmask;                                
    int fds;                       
    struct sockaddr addr;                                
    socklen_t addrlen;                                
    int fd = 0;                                
    int afd;                                
    int inet = 0;                  
    set_ps_display("PCP: wait for connection request", false); 
    FD_ZERO(&readmask);                                
    FD_SET(unix_fd, &readmask);                                
    if (inet_fd)                                
        FD_SET(inet_fd, &readmask);                            
                                    
    fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, NULL); 
    if (fds == -1){                                
        if (errno == EAGAIN || errno == EINTR)                            
            return NULL;          
        pool_error("pcp_child: select() failed. reason: %s", strerror(errno));
        return NULL;                            
    }                                
                                    
    if (FD_ISSET(unix_fd, &readmask)){                                
        fd = unix_fd;                            
    }                                
                                    
    if (FD_ISSET(inet_fd, &readmask)){                                
        fd = inet_fd;                            
        inet++;                            
    }                                
                                    
    addrlen = sizeof(addr);       
    afd = accept(fd, &addr, &addrlen); 
    if (afd < 0){                                
        /*                            
         * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK)
         * can be silently ignored.                            
         */                            
        if (errno != EAGAIN && errno != EWOULDBLOCK)                            
            pool_error("pcp_child: accept() failed. reason: %s", strerror(errno));                        
        return NULL;                            
    }                                
                                    
    if (pcp_got_sighup){                                
        pool_get_config(get_config_file_name(), RELOAD_CONFIG);
        pcp_got_sighup = 0;                            
    }                             
    pool_debug("I am PCP %d accept fd %d", getpid(), afd);
    if (inet){                                
        int on = 1;             
        if (setsockopt(afd, IPPROTO_TCP, TCP_NODELAY,                            
                       (char *) &on,                
                       sizeof(on)) < 0)                
        {                            
            pool_error("pcp_child: setsockopt() failed: %s", strerror(errno)); 
            close(afd);                        
            return NULL;                        
        }                            
        if (setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE,                            
                       (char *) &on,                
                       sizeof(on)) < 0)                
        {                            
            pool_error("pcp_child: setsockopt() failed: %s", strerror(errno));                        
            close(afd);                        
            return NULL;                        
        }                            
    }                                
                                    
    if ((pc = pcp_open(afd)) == NULL){                                
        close(afd);                            
        return NULL;                            
    }                                
    return pc;                                
}
afd = accept(fd, &addr, &addrlen);这一句,会给出和客户端通信的返回值。
原文地址:https://www.cnblogs.com/gaojian/p/2639843.html