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);
        }
相关推荐
严同学正在努力37 分钟前
从备份到恢复:我用 30 分钟恢复了误删的核心业务表
android·java·数据库·ai
#六脉神剑1 小时前
myBuilder新版本(8月,Office文件预览、Oracle数据库支持)
数据库·oracle·开发平台·数字化工具·mybuilder
花青泽1 小时前
5-数据库-SQL注入-联合查询-AND/OR绕过-day13
数据库·sql
踏着七彩祥云的小丑1 小时前
忘记Redis是否安装过时查看
数据库·redis·缓存
Nontee3 小时前
设计模式:模板方法与策略,从“每个字都认识“到能说清它们在干嘛
java·数据库·设计模式
眞bilibili3 小时前
带团队后的日常思考(十七)
数据库
laboratory agent开发3 小时前
智能体多工具串联执行中途失败,部分写入的数据如何回滚
运维·服务器·数据库
段一凡-华北理工大学4 小时前
AI推动工业智能化转型~系列文章07:分类与诊断算法体系:故障识别的完整工具箱
数据库·人工智能·算法·机器学习·分类·数据挖掘·高炉炼铁智能化
DBA_G4 小时前
南大通用GBase HD数据平台讲解
数据库
foolishlee4 小时前
Neon wal日志处理流程
数据库