1.PostgreSQL源码学习笔记(6)-查询编译
2.PostgreSQL · 源码分析 · 回放分析(一)
3.源码 | 为金融场景而生的数据类型:Numeric
4.在Linux(centos)中使用源码安装pgRouting
5.PostgreSQL14基于源码安装和入门教程
6.PostgreSQL-源码学习笔记(5)-索引
PostgreSQL源码学习笔记(6)-查询编译
查询模块是数据库与用户进行交互的模块,允许用户使用结构化查询语言(SQL)或其它高级语言在高层次上表达查询任务,并将用户的查询命令转化成数据库上的操作序列并执行。查询处理分为查询编译与查询执行两个阶段:
当PostgreSQL的后台进程Postgres接收到查询命令后,首先传递到查询分析模块,进行词法,用卡圈源码语法与语义分析。用户的查询命令,如SELECT,CREATE TABLE等,会被构建为原始解析树,然后交给查询重写模块。查询重写模块根据解析树及参数执行解析分析及规则重写,得到查询树,最后输入计划模块得到计划树。
整个查询编译的函数调用流程包括查询分析、查询重写与计划生成三个阶段。查询分析涉及词法分析、语法分析与语义分析,分别由Lex与Yacc工具完成。词法分析识别输入的SQL命令中的模式,语法分析找出这些模式的组合,形成解析树。出于与用户交互的考虑,语义分析与重写放在另一个函数处理,以避免在输入语句时立即执行事务操作。Lex与Yacc是词法与语法分析工具,分别通过正则表达式解析与语法结构定义,生成用于分析的C语言代码。
查询分析由pg_parse_query函数与pg_analyze_and_rewrite函数完成。pg_parse_query处理词法与语法分析,而语义分析与重写在pg_analyze_and_rewrite函数中进行。语义分析需要访问数据库系统表,以检查命令中的表或字段是否存在,以及聚合函数的适用性。
查询重写核心在于规则系统,存储在pg_rewrite系统表中。pb源码免费规则系统由一系列重写规则组成,包括创建规则、删除规则以及利用规则进行查询重写三个操作。规则系统提供定义、删除规则以及利用规则优化查询的功能。PG中实现多种查询优化策略,包括谓语下滑、WHERE语句合并等,通过动态规划与遗传算法选择代价最小的执行方案。
查询规划的总体过程包括预处理、生成路径和生成计划三个阶段。预处理阶段消除冗余条件、减少递归层数与简化路径生成。提升子链接与子查询是预处理中的关键步骤,通过将子查询提升至与父查询相同的优化等级,提高查询效率。提升子链接与子查询的函数包括pull_up_sublinks与pull_up_subqueries。
在路径生成阶段,优化器检查MIN/MAX聚集函数的存在与索引条件,生成通过索引扫描获得最大值或最小值的路径。表达式预处理由preprocess_expression函数完成,包括目标链表、WHERE语句、HAVING谓语等的处理。HAVING子句的提升或保留取决于是否包含聚集条件。删除冗余信息以优化路径生成。
生成路径的入口函数query_planner负责找到从一组基本表到最终连接表的最高效路径。路径生成算法包括动态规划与遗传算法,分别解决路径选择与状态传递问题。路径生成流程涉及make_one_rel函数,最终生成最优路径并转换为执行计划。
在得到最优路径后,优化器根据路径生成对应的执行计划。创建计划的入口函数create_plan提供顺序扫描、采样扫描、索引扫描与TID扫描等计划生成。stl源码分析整理计划树函数set_plan_references负责最后的细节调整,优化执行器执行效率。代价估算考虑磁盘I/O与CPU时间,根据统计信息与查询条件估计路径代价。
查询编译与规划是数据库性能的关键环节。PostgreSQL通过高效的查询分析、重写与规划,生成最优执行计划,显著提高查询执行效率。动态规划与遗传算法等优化策略的应用,确保了查询处理的高效与灵活性。
PostgreSQL · 源码分析 · 回放分析(一)
在数据库运行中,可能遇到非预期问题,如断电、崩溃。这些情况可能导致数据异常或丢失,影响业务。为了在数据库重启时恢复到崩溃前状态,确保数据一致性和完整性,我们引入了WAL(Write-Ahead Logging)机制。WAL记录数据库事务执行过程,当数据库崩溃时,利用这些记录恢复至崩溃前状态。
WAL通过REDO和UNDO日志实现崩溃恢复。REDO允许对数据进行修改,UNDO则撤销修改。REDO/UNDO日志结合了这两种功能。除了WAL,还有Shadow Pagging、WBL等技术,但WAL是主要方法。
数据库内部,日志管理器记录事务操作,缓冲区管理器负责数据存储。当崩溃发生,恢复管理器读取事务状态,直销公司源码回放已提交数据,回滚中断事务,恢复数据库一致性。ARIES算法是日志记录和恢复处理的重要方法。
长时间运行后崩溃,可能需要数小时甚至数天进行恢复。检查点技术在此帮助,将脏数据刷入磁盘,记录检查点位置,确保恢复从相对较新状态开始,同时清理旧日志文件。WAL不仅用于崩溃恢复,还支持复制、主备同步、时间点还原等功能。
在记录日志时,WAL只在缓冲区中记录,直到事务提交时等待磁盘写入。LSN(日志序列号)用于管理,只在共享缓冲区中检查。XLog是事务日志,WAL是持久化日志。
崩溃恢复中,checkpointer持续做检查点,加快数据页面更新,提高重启恢复速度。在回放时,数据页面不断向前更新,直至达到特定LSN。
了解WAL格式和包含信息有助于理解日志内容。PG社区正在实现Zheap特性,改进日志格式。WAL文件存储在pg_wal目录下,大小为1GB,与时间线和LSN紧密关联。事务日志与WAL段文件相关联,比比奇 源码根据特定LSN可识别文件名和位置。
使用pg_waldump工具可以查看日志内容,理解一次操作记录。日志类型包括Standby、Heap、Transaction等,对应不同资源管理器。PostgreSQL 包含种资源管理器类型,涉及堆元组、索引、序列号操作。
标准记录流程包括:读取数据页面到frame、记录WAL、进行事务提交。插入数据流程生成WAL,复杂修改如索引分裂需要记录多个WAL。
崩溃恢复流程从控制文件中获取检查点位置,严格串行回放至崩溃前状态。redo回放流程与记录代码高度一致。在部分写问题上,FullPageWrite(FPW)策略记录完整数据页面,防止损坏。WAL错误导致部分丢失不影响恢复,数据库会告知失败。磁盘静默错误和内存错误需通过冗余校验解决。
本文总结了数据库崩溃恢复原理,以及PostgreSQL日志记录和崩溃恢复实现。深入理解原理可提高数据库管理效率。下文将详细描述热备恢复和按时间点还原(PITR)方法。
源码 | 为金融场景而生的数据类型:Numeric
高日耀,资深数据库内核研发人员,毕业于华中科技大学。他专注于研究主流数据库架构与源码,长期参与分布式数据库内核研发。他的专业领域包括分布式 MPP 数据库 CirroData 内核开发(东方国信)与 MySQL 系列产品内核开发(青云科技)。
在数据库设计和源码实现领域,高日耀曾经参与过数据类型(如 Numeric、Datetime、Timestamp、varchar 等)的设计与实现。他特别深入研究了 Numeric 类型,这个标准 SQL 的一部分,与 Decimal 类型等价,主要用于金融场景,存储大数值,对数据的精度有极高的要求。
以下内容基于 PostgreSQL 源码,解析了 PostgreSQL 中 Numeric 类型的内存计算结构和磁盘存储结构。
在编程过程中,我们通常使用内置的 4 字节 float 和 8 字节 double 类型进行加减乘除运算。然而,浮点数通过科学计数法存储,在二进制与十进制转换过程中,对于某些二进制数,其精度会有缺失。而金融场景中动辄处理巨大数值,且对精度要求极高,任何微小的精度损失都是不可接受的。市面上的数据库基本都包含了 Numeric 类型,通过字符串精确存储每一位数,确保浮点数无法达到的精确计算。
以下为 Numeric 类型的语法简介:
NUMERIC(precision, scale)
例如:.,其中 precision 为 5,scale 为 3。
在不指定精度的情况下,数值类型的取值范围如下:
以下是 Numeric 类型的特殊值——NaN(代表 "not-a-number")。在 SQL 中作为常量使用时,需要加上引号,例如:
在 SQL 中,Numeric 数据的流向涉及数据库执行流程,包括创建表、插入数据等操作。下面以创建 test 表并插入数据为例,关注写入 Numeric 数字的内存表示、定义为 NUMERIC(5,2) 的数据结构在内存中的表示方式,以及数据写入磁盘后的存储结构。
数据在内存中的存储结构与落盘时的存储结构不同,落盘时需要去掉内存中所占用的无效字节。例如,varchar() 在内存中分配了 个字节,而实际只写入了 "abc" 三个字节,因此,尽管内存中分配了 个字节,落盘时实际上只使用了 3 个字节。如果数据量非常大,直接写入磁盘而不进行处理,将会浪费大量磁盘空间。
接下来,我们将解析 Numeric 类型在磁盘上的存储结构。结构体 NumericData 包含了 NumericLong 和 NumericShort 的 union 字段,用于描述最终写入磁盘的结构。下面详细介绍这些结构体的组成部分。
在后续文章中,我们将基于内存计算结构,深入探讨 Numeric 类型在代码中的实现原理,通过数学公式解析二进制与十进制转换为何会产生精度损失的问题。此外,我们还将继续解析 MySQL / Oracle 等数据库中 Numeric 类型的设计与源码实现。
在Linux(centos)中使用源码安装pgRouting
在Linux(centos)环境下使用源码安装pgRouting前,请先确保已阅读并安装了PostgreSQL和PostGIS。
本文将介绍如何安装pgRouting 2.6.3版本,其源码包可从以下地址下载:
github.com/pgRouting/pg...
一、解压pgRouting源码包
将下载的源码包pgrouting-2.6.3.tar.gz复制到/usr/local/src目录,并执行解压操作:
解压完成后,将生成一个名为pgrouting-2.6.3的目录。
二、配置PostgreSQL环境变量
编辑/etc/profile文件,添加以下内容:
保存并退出,然后使profile配置文件立即生效:
三、编译源代码
进入pgrouting-2.6.3目录,创建build新文件夹,并进入该文件夹:
使用cmake指令编译源代码,指定pgRouting安装路径为/usr/local/pgrouting-2.6.3:
执行make编译源代码,然后使用make install安装pgrouting-2.6.3:
为避免pgrouting找不到CGAL动态库,将CGAL动态库路径添加到ld.so.conf文件中:
编辑/etc/ld.so.conf,添加路径:
使ld.so.conf文件立即生效:
至此,pgrouting-2.6.3已成功安装。
四、测试安装
切换到postgres用户,启动PostgreSQL数据库(若未启动则启动),进入psql:
连接test数据库(可创建任意名称的数据库),创建pgrouting插件:
查看test数据库中现有的所有插件,可以发现已成功安装了postgis和pgrouting插件。
PostgreSQL基于源码安装和入门教程
PostgreSQL 源码安装入门教程
本文将引导您在openEuler . LTS-SP3系统上基于源码安装并配置PostgreSQL ,包括操作系统环境设置、网络配置、软件包安装、用户和数据盘创建,以及数据库的初始化、启动和管理。1.1 操作系统环境
安装openEuler后,确保系统安装了bc命令(若缺失,后续会安装)。1.2 网络配置
通过Nmcli配置网络,首先检查并设置网络接口ens的IP地址,无论是自动获取还是静态配置。1.3 更新系统与工具安装
更新软件包并安装bc、vim、tmux和tar等工具,以支持后续操作。1.4 用户与数据盘创建
创建postgres用户和用户组,以及可能的专用数据盘,如NVMe SSD,用于提高性能。2. 安装与配置
2.1 下载与解压
以root权限下载并解压PostgreSQL 的源代码压缩包。2.2 安装与初始化
按照指导进行编译和安装,初始化数据库并设置启动参数。2.3 启动与管理
启动数据库,登录并创建必要用户、数据库和表空间。3. 开机自动启动
3.1 init.d环境
使用start-scripts中的脚本配置init.d,确保PostgreSQL在系统启动时自动运行。3.2 systemd环境
为PostgreSQL创建systemd服务文件,确保启动和管理的自动化。4. psql操作示例
展示如何使用psql进行数据库操作,包括创建数据库、模式、表和数据插入等。5. 远程连接
讲解如何配置防火墙以允许远程连接。 通过以上步骤,您将掌握PostgreSQL 的源码安装和基本管理,准备好进行数据管理和应用程序开发。PostgreSQL-源码学习笔记(5)-索引
索引是数据库中的关键结构,它加速了查询速度,尽管会增加内存和维护成本,但效益通常显著。在PG中,索引类型丰富多样,包括B-Tree、Hash、GIST、SP-GIST、GIN和BGIN。所有索引本质上都是独立的数据结构,与数据表并存。
查询时,没有索引会导致全表扫描,效率低下。创建索引可以快速定位满足条件的元组,显著提升查询性能。PG中的索引操作函数,如pg_am中的注册,为上层模块提供了一致的接口,这些函数封装在IndexAmRoutine和IndexScanDesc中。
B-Tree索引采用Lehman和Yao的算法,每个非根节点有兄弟指针,页面包含"high key",用于快速扫描。PG的B-Tree构建和维护流程涉及BTBuildState、spool、元页信息等结构,包括创建、插入、扫描等操作。
哈希索引在硬盘上实现,支持故障恢复。它的页面结构复杂,包括元页、桶页、溢出页和位图页。插入和扫描索引元组时,需要动态管理元页缓存以提高效率。
GiST和GIN索引提供了更大的灵活性,支持用户自定义索引方法。GiST适用于通用搜索,而GIN专为复合值索引设计,支持全文搜索。它们在创建时需要实现特定的访问方法和函数。
尽管索引维护有成本,但总体上,它们对提高查询速度的价值不可忽视。了解并有效利用索引是数据库优化的重要环节。