开发者学堂课程【PolarDB for PostgreSQL 内核解读系列课程:【视频】PostgreSQL 系统概述】学习笔记(一),与课程紧密连接,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/1042/detail/15199
【视频】PostgreSQL系统概述
内容介绍
一.课程目标及策略
二.PostgreSQL 概述(历史、架构)
三.PostgreSQL 安装启动
四.PostgreSQL 常用命令、调试
五.总结
一. 本系列教程介绍
1. 课程目标及策略
面向的受众主要是有开源群里的成员,据统计主要是dba比较多,另外还有高校的一些学生、内核开发爱好者。
针对DBA,经常会遇到问题很麻烦。一般会到网上找答案,可能答案有的时候找不到会很头疼。在群里老师也回复了很多同学的问题,问题比方说有同学说某某问题,具体说是什么原因。其实这个某某的分支很多,不可能把他的所有用法都知道,那怎么回答这个问题呢?
解决办法就是简单的看一下相关代码的几个分支里面的控制参数是怎样的,这个可以很清楚的显示出来。
针对DBA这部分,通过这个课程的学习,其余同学如果发现问题可以简单的通过查看代码的方法去定位到这个问题到底是什么样的问题,不说解决但至少知道应该是怎么配置怎么用的。
对于数据库内核感兴趣的同学,可能还没接触到数据库的内核,缺的是内核的基本的原理和代码的实现。在整个课程中,会讲这部分的架构、原理,还有最终的实现。这样才会更好的全面了解这个系统,希望能做到学习以后的同学可以进行简单的一些功能的开发或者更深入的自学。
一些内核开发的爱好的同学可能都是PG的内核的高手,在这里可以共同学习、共同成长。群里面很多同学爱问问题,有些人喜欢帮解答,这样就可以共同成长,老师只是提供一个共同学习的机会。
课程的策略,第一是章节的设置参照了彭志勇老师的《postgre sql数据库内核分析》,这本书十年出版,在数据库里比较经典,尤其是在国内。前面一些章节是参照这本书,目的是有些内容可能是课程里面有而书里没有,也有可能一部分是书里有但课程没讲到的。所以希望大家可以同步的看,老师把原理讲清楚以后再看书也会看得比较容易,两个互补,讲到了也知道在哪里找。
第二是每个章节会先介绍它的架构、原理、使用方法,最后再介绍代码。
第三,时间允许的情况下会结合之前的开发的patch,介绍各个模块具体的功能和关系,包括polarDB在某个模块里做了哪些改动也会提一下,包括前沿的一些技术比如存储引擎,会介绍产品相关的一些新的基础和用法。
2. 课程内容设置
课程的内容设置主要有15个章节,这个过程可能会做细微的调整,比如事务的内容很多,列出来需要比较多的时间,因为CLOG和锁机制都放在这里,内容就比较多,存储引擎两节讲完也很难。
因此有的章节会进行一些调整,如果存储引擎前面讲的快,后面就加点别的内容,如果两节讲不完就加一节课,目前后面的课程还没有准备好。
另外在上课过程中,同学有自己的一些想法,比如哪个地方没讲透或者哪个地方需要特殊讲,大家可以把这个意见提出来,因为我们的目标是大家共同学习,共同成长。
二. PostgreSQL 概述(历史、架构)
PostgreSQL 历史
postgre sql的系统历史最早是1977年MICHAEL STONEBRAKER在伯克利做了postgre的原型项目,包括这个ingres公司的成立,被infomix收购,这个过程是在1977到1985这十年间,MICHAEL STONEBRAKER投入很多。
左上面这张图是伯克利大学,老师在美国工作几年去过两次,它在硅谷的北边,硅谷内过了金门大桥在金州勇士的足球场旁边。这个学校比较知名的是数据库的相关的老师和课程,是数据库领域非常知名的学府。
1994年到1996年,是SQL标准的引入,andrew yu写了很多代码,现在看这个代码和跟那个时候比没有太多改动,基本上是andrew yu写完了就是非常好的版本,现在可能加了一些新的算子或者语法,但是基本上走的流程还是原来的东西。
1996年开源了之后,1998年包括MVCC、WAL、存储过程、等等这些都是重量级的,这个时候是一个发展很快的过程。基本上到七点几的时候已经是一个比较成熟的产品。从国内这边来看,这十年从8.2开始到后期的9.2,大家印象中8.2用的是最多的。
到了2018年,pg11是近期比较稳定的一个版本,现在很多也都是pg11来搞的。之后每年一个版本一直到15,2022年的发展整体较快。
右上角这张图可以看一下,这里的jolly chen、Andrew yu都是中国人,tom lane、bruce momjian现在都一直在活跃在PG的第一线,之前在硅谷经常去参加pg相关的一些社区的组织的活动。
数据库领域开源生态
之后讲一下数据库领域开源的生态。
从数据库开源角度来看,mysql和PG这两个是最重要的两个产品,发展到现在也是最知名的。
阿里从单机这边最早的时候开aliSQL,是基于mysql的版本做了很多patch的优化,包括TDDL,还有近期刚开源的polarDB for pg和PolarDB-x是mysql分布式的版本,这些都是与mysql和PG有关的,从上面这张图可以看到这里与他们有关的产品是非常多的。
PostgreSQL架构
从最左边是用户client,比如一个用户没有访问数据库,首先在client端,通过psql内部相当于集成了一个6pq的协议的库。通过库就可以通过6pq的协议互相发消息,通过psql首先连postgre master进程,这个进程是第一个启动的进程,其他进程都是他的子进程。启动之后不停的循环去监听端口,这里面很重要的一个参数是pot端口,默认如果不改的话是5432端口一直监听。
一连到他他就知道有人想要请求数据库的服务,他不会自己做查询,会fog出一个子进程,他俩都是postgre sql的进程,只是它的启动方式不同,所以叫postgre master。后面的这些进程也都是postgre sql的进程,只是这个针对不同的客户端启动一个单独的进程来对它提供服务。这些进程包括vacuum进程、日志进程、数据统计的进程、数据页的后台写入的进程等等,是在后台帮助数据库系统来运维做服务的。这些进程下个章节会介绍到。
下一层是这些系统都会跟下面的文件打交道,存储引擎里面会见到比如数据文件、索引文件、Index或者wal日志,他们分别都是什么样格式组成的,里面记录的数据类型和数据是什么样子的,大家都会在存储引擎里面深入的去学习和了解。
这个进程会共同访问shared memory ,shared memory可以帮助系统加速,如果每个进程读取某一个数据或者数据页的时候都到磁盘去读,改完了再写回来,再读再写,这个磁盘的性能就跟不上了。所以大家在访问某个数据的时候先到shared memory去读数据,如果没有再到磁盘里面加载memory进行读取。所以大家可以共享这个数据叫shared memory。另外一个是individual memory,主要是各个进程自己的memory,比如autovacuum是和vacuum进程有关的, work memory是进程里面比如某个算子的内存就可以用work memory。进程申请memory的过程。剩下的主要是存储引擎那边会介绍。
Postgre SQL 逻辑的架构
最后讲一下postgre SQL逻辑的架构。逻辑架构主要是介绍文件数据data是怎么保存的
data首先是按照数据库来保存的。比如database template0第一个生成的模板数据库是unchangeable不能改的。
基于这些模板的数据库,就可以生成一个postgres数据库,这个数据库是默认就有的。先创建数据库的时候,这些内容已经都有了,默认是创建好的,后面如果再加新的数据库是可选的。如果要直接用postgre这个数据库也是可以的。
端口5432的默认的数据库叫postgres,默认的schema是public,要记住有些默认值是是比较重要的,包括system的schema会在第二节里面给大家介绍。system schema是怎么生成系统表的、它的原理、包含的内容、初始化的过程是怎样的。这些都是在数据化的过程中做的一些事情,下周可以详细的去介绍,这里面有一些公共的部分呢,会放到global目录里。
这个逻辑架构可能看起来更顺费眼一点。目录是叫pgdata。这里面有美元号,是linux的一个环境变量。输入环境变量就会把这个数据linux安装到目录里面,有post great contig的配置文件、针对这些数据库、各个数据库模板库template1、postgres、还有自己建的库,都是在base目录下的。
base目录下相当于这里面都会存各个数据库以及数据库底下会存建的一些表、索引、fsm还有可行性的map。这些文件具体的格式和内容会在存储引擎里做更深入的一些介绍,全局的一些信息包括control的一些信息都会在global里。
逻辑复制或者统计信息是其他的一些字幕。这里面可能还要提到tbspc是什么意思?是做什么的呢?它是帮助管理数据的,现在这些数据全都是放在杯子下面,没有办法去把他放在不同的磁盘里。比如现在机器有四块盘,创建一个tbspc把它打散到不同的盘里,再创建这个表就可以让他放到不同的tbspc里,可以更好地管理磁盘,做均衡。
之后讲解模块及代码的目录结构哈,首先呢,看一下这个这个程序,一般C的程序都有main函数,main函数进来之后,正常情况下都会先启动post master进程,它会发挥出不同的postgres相关的一些进程。
在postgres进程里如果收到了libpq的请求,他会首先对这个相关的请求进行post形成post tree,到底是utility的命令还是sql,到时是reright或者怎么样,要产生一个plan,最终在执行引擎执行。
这里面依赖了底层的比如元数据的一些提取方法,存储的一些管理等等,都是会有依赖的。
右面的目录执行是执行引擎,优化器optimizer,parser,每一个部分包括存储引擎都是介绍的比较清楚的,pg相对来说比较容易流行,相对的代码是规划的比较好的,这样看起来就比较简单。
这两部分先带大家实际去看一下数据目录的情况。这是之前安装到Pgdata目录下的数据,下面看一下这个里边有什么内容:
有base目录,template0、template1这些数据库、Global都放在这里。
上面这些是base里的目录,在目录里除了可以看到数据文件之外,文件还对应了fsm、vm相关的一些类型的文件,帮助大家管理空闲空间和可行性的相关内容,到时候相应的章节会再介绍。
这里可以看到在global里面有一个pg control是很重要的,整个系统的控制文件,包括文件映射相关, internal的相关的一些都是很重要的全局文件。日志是按照日期来定义,它就可以循环的利用它记录整个启动或者执行的一些流程。事物有关、统计信息有关、tbspc有关的,跟事务知识有关的wal日志的一些原理、代码如何实现,后面都会讲到。
之后再看一下代码的目录。主要是下载的代码,这里比较重要是contrib,相当于一些很重要的插件,比如pageinspect。看不懂怎么办,就可以利用这种工具帮他去查看,包括你oid怎么能转换成对应的名字或者这个buffercatch的查看,包括一些可见性文件的查看,这些都是在插件里实现的。要进到这个插件目录,单独去make才能编译出来,有的时候不用步编译也可以。
SRC是实际的代码目录,这个目录里比较重要的一个backend,所有的C文件在里面。
include就是”.H”,“.H”一般由C和H组成的这个C语言。common是一些公共的函数、库什么的在里边。
test里很重要的一个就是regress,所有的测试用例都在里面。这里面有很多SQL,大家可以学习来参考来用。
看一下backend的目录。比如索引access、启动bootstrap、catalog、commands、执行引擎executor、优化器parser、partitioning,看名字就知道它的作用了。
比如说存储引擎,有buffer、file、free space怎么管、相关的锁是怎样的、page的结构是怎样的,都在这里面会介绍。
三.PostgreSQL 安装启动
pg源码编译安装
大家熟悉一下环境。编译安装,主要是源码的安装:
git clone https://aithub.com/postgres/postgres.ait
cd postgres
git branch -r|grep -v '\->'| while read remote; do git branch--track "${remote#origin/}" "$remote"; done
git fetch --all
git pull -all
git branch
git checkout REL_11_STABLE
首先会用git命下载源码,取得他的分支信息,查看分支信息之后把代码checkout下来,这样就能得到想要的版本代码。pg代码库里管理了各个版本的代码,所以需要找到想要的这个版本的代码。
./configure-help
./configure--prefix=/home/michael.yw/pghome--enable-debug--enable-cassert CFLAGS="-ggd db -00-g3-Wall -fno-omit-frame-pointer-fstack-protector-strong"-- Debug版
./configure--prefix=/home/michael.yw/pghome--enable-debug--enable-cassert CFLAGS="-g-02 -Wall-fno-omit-frame-pointer-fstack-protector-strong"-Release版
make -sj && make install
源码的编译安装是通过config配置一下,配置的时候包括指定安装的目录是什么,参数包括现在是不是第八个版本、优化的等级是怎样的等等这样的信息,配置完以后就去make或make install就会编译并且进行安装。
vi ~.bashrc
export PATH="/home/michael.yw/pghome/bin:$PATH"exportLD_LIBRARY_PATH="/home/michael.yw/pghome/lib:$LD_LIBRARY_PATH
export PGHOME="/home/michael.yw/pghome
export PGDATA="/home/michael.yw/pgdata
source~/.bashrc
编译安装完以后配置一些环境变量,环境变量主要是跟path有关的,path安装完成之后以后,比如要执行psql命令的时候,它会自动到path目录定位,这样目录信息就不需要了。包括ibrary的目录的信息,包括pg home和pg data相关的一些配置,这个相当于更好的去使用和定位这些目录,后面用起来会更方便。
PG初始化数据库启动
1. 初始化数据库
initdb-D/home/michael.yw/pgdata
后面会去讲源码的情况。这里可以看到首先创建了一个子目录,做了一些配置,运行了一个bootstrip的脚本。
2. 参数修改
maxconnections=100
max_wal_senders=10
max_replication_slots=10
max_worker_processes=10
shared_preload_libraries='pg_statstatements listen_addresses='*
port=6688
logging_collector=on
log_directory='log
log_filename=postgresql-%a.log
log_truncate_onrotation=on
log_rotation_age=1d
log_rotation_size=0
log_checkpoints=on
log_connections=on
log_disconnections=on
log_error verbosity=verbose
log_line_prefix='%m[%p]
log_timezone='PRC'
log_autovacuum_min_duration=0
运行以后成功了,用pg ctl这个命令启动,做一些配置再启动,配置的时候可以配置成自己喜欢的端口,因为比如5432这种用的比较多的机器可能跟别人冲突,所以需要配置一个端口。
3. 数据库的启动和停止
pg_ctl-D/home/michael.ywxpgdata-1/home/michael.yw/pgdata/logfile1 start
pg_ctl-D/home/michael.yw/pgdata-1/home/michael.yw/pgdata/logfile1 stop
数据库的启动和停止是用 pg ctl 的命令来启动相关的目录,对应的pg的程序包含start stop,指定刚才安装的数据目录的位置;-l指定启动时的日志的位置。











