近期将加入关系型数据库存储领域,很有幸加入到了一家以PG 为核心生态的数据库内核研发的领域,能够深入研究 这个世界上最为先进的开源关系型数据库的内核设计。
简介
简单看一下PG的36年的历史(可能也是PG 用C语言实现的原因,毕竟当时C++才刚刚开始,PG 6.0都出来了,C++ 98标准还没出来):
阶段1: 伯克利大学的 postgres 项目
- 1986年:PG 在 加州伯克利大学的 Michael Stonebraker 教授 领导下进行开发
- 1987年 完成了一个版本的demo,包含 数据模型 以及 规则的定义(角色,权限 等多租户形态) 和 关系型数据的存储 都已经支持了。
- 1988年 在 ACM-SIGMOD 顶会展示了这个关系型数据存储系统的设计。
- 1989年 发布了第一个版本
- 1990年 因为用户对 规则系统的需求,重新设计了 规则系统 并发布了第二个版本。
- 1991年 发布了第三个版本,支持了 多种存储管理器 ,优化执行器
- 1992年 postgres 项目已经拥有了超过 2000 个服务于科研的计算项目。
- 1993年,因为随着postgres 项目用户的极速增加,仅仅由一个大学教授以及他带领学生们来进行维护远远不够,源代码的维护消耗了太多的用于研究数据库的时间,所以postgres 项目终结于 4.2版本。
阶段2: Postgres95 阶段
- 1994年 Andrew Yu 和 Jolly Chen 向POSTGRES中增加了 SQL 语言的解释器,将 Postgres 命名为 Postgres95 进行开源。PG95 性能上相比于 前面的 PG 版本拥有 30-50%的性能提升。
阶段3: PostgreSQL 阶段
- 1996年 重新将 Postgres95 改名为 PostgreSQL ,版本号从 6.0开始。
现在的github 上的pg 将 95版本加入了进来
源码编译 及 运行
个人编译环境是 unbuntu20.04,该编译步骤在其他系统中都一样的,PG 版本是 REL_12_STABLE 。
-
依赖库安装:sudo apt install build-essential libreadline-dev zlib1g-dev -y -
获取源码:wget https://ftp.postgresql.org/pub/source/v12.11/postgresql-12.11.tar.bz2 -
tar xvf postgresql-12.11.tar.bz2 && cd postgresql-12.11 -
编译
1. ./configure --prefix=/home/zhg/pgsql --enable-debug
2. make world -j && make install-world
3. mkdir /home/zhg/pgsql/data
4. export LD_LIBRARY_PATH=/home/zhg/pgsql/lib:$LD_LIBRARY_PATH
-
初始化数据库 /home/zhg/pgsql/bin/initdb -D /home/zhg/pgsql/data -
启动PG /home/zhg/pgsql/bin/pg_ctl -D /home/zhg/pgsql/data -l logfile start ,logfile是postgres 的log文件 -
创建数据库 /home/zhg/pgsql/bin/createdb testdb -
终端进入数据库 /home/zhg/pgsql/bin/psql testdb
GDB 调试
我们期望追踪 insert 语句 以及 select 语句 在整个PG 中的执行链路。 1.提前建好表 执行 psql testdb 之后 输入一个建表命令,建表的时候不带索引,后面写入的时候只会写入 heap 存储引擎,不会查索引了。
create table a(id int, c1 int, c2 int, c3 int);
2. 启动gdb 并设置 源代码目录 另外启动一个终端,能够确认知道前面安装 pg 时的源码目录:
gdb attach -p xxxiod gdb attach到 postgres 的交互进程 id,这样和终端命令的执行才能阻塞式得执行, 方便我们在gdb端check 执行逻辑。
gdb 内部输入 dir /home/zhg/postgresql-12.11 pg 源代码目录。
gdb 内部输入 layout src ,能够看到整个源代码的调用链路了,后续的 调试也能够实时展示整个代码的链路(对于查看一些 inline 函数的调用逻辑的时候可能需要 layout next,通过查看汇编中的变量进行确认):
3. 开始调试 在 psql 所在的链接终端输入插入数据的命令,为建表时的4个字段分别插入10 条数据(插入逻辑是一样的, 方便我们能够反复快速调试)。
insert into a select generate_series(1,10), random()*100, random()*100, random()*100;
此时,因为我们的另一个终端的 gdb attach 到了 postgres 的交互,所以这个命令会阻塞,需要我们在 gdb 的终端主动进行执行。
在 gdb 所在终端,我们只需要反复执行以下几个命令,就好了:
n 单步执行s step到函数内部p 打印各种变量 以及 指针变量内容
|