PostgreSQL源码分析——psql

psql是一个PostgreSQL数据库自带的客户端工具,用来与数据库进行交互,当然,你也可以用其他工具。这里,我们简单分析一下psql工具的实现。

主流程如下

psql的核心功能,连接数据库,执行用户的命令,其中连接到数据库需要经过认证,这里只分析口令认证的情况。加密口令认证要求客户端提供一个经过MD5加密的口令进行认证,该口令在传送过程中使用了结合salt的单向MD5加密,增强了安全性。

当然,与数据库的核心交互还是通过libpq实现的。具体的可参考官方文档数据库连接控制函数

c 复制代码
main
--> parse_psql_options(argc, argv, &options);
    // 连接数据库,中间会有认证这块,有不同的认证方法,这里列的是口令认证方式的流程
--> do 
    {
         // 输入host、port、user、password、dbname等信息
         PQconnectdbParams(keywords, values, true);
         --> PQconnectStartParams(keywords, values, expand_dbname);
             --> makeEmptyPGconn();
             --> conninfo_array_parse(keywords, values, &conn->errorMessage, true, expand_dbname);
             --> fillPGconn(conn, connOptions)
             --> connectDBStart(conn)
                 --> PQconnectPoll(conn)    // 尝试建立TCP连接
                     --> socket(addr_cur->ai_family, SOCK_STREAM, 0);
                     --> connect(conn->sock, addr_cur->ai_addr, addr_cur->ai_addrlen)
         --> connectDBComplete(conn);
             // 认证这块与数据库服务端交互以及状态很多,这里没有全部列出。
             --> PQconnectPoll(conn);
                 --> pqReadData(conn);
                     --> pqsecure_read(conn, conn->inBuffer + conn->inEnd, conn->inBufSize - conn->inEnd);
                         --> pqsecure_raw_read(conn, ptr, len);
                             --> recv(conn->sock, ptr, len, 0);
                 --> pg_fe_sendauth(areq, msgLength, conn);
                     --> pg_SASL_init(conn, payloadlen)
                         --> conn->sasl->init(conn,password,selected_mechanism);
                             --> pg_saslprep(password, &prep_password);
                         --> conn->sasl->exchange(conn->sasl_state, NULL, -1, &initialresponse, &initialresponselen, &done, &success);
                             --> build_client_first_message(state);
                                 --> pg_strong_random(raw_nonce, SCRAM_RAW_NONCE_LEN)
         PQconnectionNeedsPassword(pset.db)     // 是否需要密码,如果需要,等待用户数据密码

    }
    // 进入主循环,等待用户输入命令,执行命令
--> MainLoop(stdin);  
    --> psql_scan_create(&psqlscan_callbacks);
    --> while (successResult == EXIT_SUCCESS)
        {
            // 等待用户输入命令
            gets_interactive(get_prompt(prompt_status, cond_stack), query_buf);

            SendQuery(query_buf->data); // 把用户输入的SQL命令发送到数据库服务
            --> ExecQueryAndProcessResults(query, &elapsed_msec, &svpt_gone, false, NULL, NULL) > 0);
                --> PQsendQuery(pset.db, query);    // 通过libpq与数据库交互
                --> PQgetResult(pset.db);
        }
相关推荐
llxxyy卢2 小时前
JWT安全&预编译CASE注入
数据库·sql·安全
大布布将军9 小时前
⚡️ 深入数据之海:SQL 基础与 ORM 的应用
前端·数据库·经验分享·sql·程序人生·面试·改行学it
JIngJaneIL9 小时前
基于java+ vue农产投入线上管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot
源代码•宸10 小时前
goframe框架签到系统项目(BITFIELD 命令详解、Redis Key 设计、goframe 框架教程、安装MySQL)
开发语言·数据库·经验分享·redis·后端·mysql·golang
川贝枇杷膏cbppg10 小时前
Redis 的 AOF
java·数据库·redis
TG:@yunlaoda360 云老大10 小时前
如何在华为云国际站代理商控制台进行SFS Turbo的性能与容量核查?
服务器·网络·数据库·华为云
ytttr87310 小时前
MATLAB基于LDA的人脸识别算法实现(ORL数据库)
数据库·算法·matlab
云老大TG:@yunlaoda36011 小时前
如何进行华为云国际站代理商跨Region适配?
大数据·数据库·华为云·负载均衡
思成不止于此11 小时前
【MySQL 零基础入门】事务精讲(二):ACID 特性与并发问题
数据库·笔记·学习·mysql
Boilermaker199211 小时前
[MySQL] 初识 MySQL 与 SQL 基础
数据库·mysql