浅聊openGauss体系架构

浅聊 openGauss 体系架构

2020 年 7 月 openGauss 刚刚开源,我便开始对 openGauss 数据库的学习。根据以往学习数据库的经验,最先想了解的是 openGauss 数据库的架构,希望对即将使用的数据库各个模块有所了解。但鉴于时间有限,仅有的资料图是源码 doc 目录内的"openGauss 逻辑结构图",便针对该图做了简单介绍,并形成文档《浅聊 openGauss 逻辑架构》,感兴趣的小伙伴可以参考。

虽然已发表关于 openGauss 逻辑架构介绍的文章供大家参考,但总感觉缺少点什么(想念学习 Oracle 时的那张体系架构图)。今年初准备培训资料时参考相关资料绘制了一份简易的 openGauss 体系架构图,后来因为忙于其他工作,把这个事情忘记了。借着本次墨天轮举办的"我的国产数据库之路",使我重新想起了这件事情,希望将这张图和相关介绍分享出来供大家参考。

说明: 本文内容仅代表个人观点。

一、首先了解一下架构图中的 Instance 部分

学习过 Oracle 等主流数据库的小伙伴都清楚,Instance 部分其实主要指的是数据库运行时的内存部分。 openGauss 属于单进程多线程模型的数据库,客户端可以使用 JDBC/ODBC/Libpq/Psycopg 等驱动程序,向 openGauss 的后端管理线程 GaussMaster 发起连接请求。

补充知识点:

  • JDBC

    JDBC(Java Database Connectivity,Java 数据库连接)是一种用于执行 SQL 语句的 Java API,可以为多种关系数据库提供统一访问接口,应用程序可基于它操作数据。openGauss 库提供了对 JDBC 4.0 特性的支持,需要使用 JDK1.8 版本编译程序代码,不支持 JDBC 桥接 ODBC 方式。

  • ODBC

    ODBC(Open Database Connectivity,开放数据库互连)是由 Microsoft 公司基于 X/OPEN CLI 提出的用于访问数据库的应用程序编程接口。应用程序通过 ODBC 提供的 API 与数据库进行交互,增强了应用程序的可移植性、扩展性和可维护性。openGauss 目前提供对 ODBC 3.5 的支持。但需要注意的是,当前数据库 ODBC 驱动基于开源版本,对于 tinyint、smalldatetime、nvarchar2 类型,在获取数据类型的时候,可能会出现不兼容。

  • Libpq

    Libpq 是 openGauss 的 C 语言程序接口。 客户端应用程序可以通过 Libpq 向 openGauss 后端服务进程发送查询请求并且获得返回的结果。需要注意的是,在官方文档中提到,openGauss 没有对这个接口在应用程序开发场景下的使用做验证,不推荐用户使用这个接口做应用程序开发,建议用户使用 ODBC 或 JDBC 接口来替代。

  • Psycopg

    Psycopg 可以为 openGauss 数据库提供统一的 Python 访问接口,用于执行 SQL 语句。openGauss 数据库支持 Psycopg2 特性,Psycopg2 是对 libpq 的封装,主要使用 C 语言实现,既高效又安全。它具有客户端游标和服务器端游标、异步通信和通知、支持"COPY TO/COPY FROM"功能。支持多种类型 Python 开箱即用,适配 PostgreSQL 数据类型;通过灵活的对象适配系统,可以扩展和定制适配。Psycopg2 兼容 Unicode 和 Python 3。

GaussMaster 线程接收到客户端程序发送过来的服务请求后,会根据收到的信息会立即 fork()一个子线程,这个子线程对请求进行身份验证成功后成为对应的后端业务处理子线程( gaussdb )。之后该客户端发送的请求将由此业务处理子线程(gaussdb)负责处理。当业务处理子线程(gaussdb)接收到客户端发送过来的查询(SQL)后,会调用 openGauss 的 SQL 引擎对 SQL 语句进行词法解析、语法解析、语义解析、查询重写等处理操作,然后使用查询优化器生成最小代价的查询路径计划。之后,SQL 执行器会按照已制定的最优执行计划对 SQL 语句进行执行,并将执行结果反馈给客户端。

在 SQL 执行器的执行过程中通常会先访问内存的共享缓冲区(如:shared buffer、cstore buffer、MOT 等),内存共享缓冲区缓存数据库常被访问的索引、表数据、执行计划等内容, 共享缓冲区的高速 RAM 硬件,为 SQL 的执行提供了高效的运行环境,大幅减少了磁盘 IO,极大地提升了数据库性能,是数据库非常重要的组件之一。

如图所示:

  • shared buffer 是行存引擎默认使用的缓冲区,openGauss 的行存引擎是将表按行存储到硬盘分区上,采用 MVCC 多版本并发控制,事务之间读写互不冲突,有着很好的并发性能,适合于 OLTP 场景。
  • cstore buffers 是列存引擎默认使用的缓冲区,列存引擎将整个表按照不同列划分为若干个 CU(Compression Unit,压缩单元),以 CU 为单位进行管理,适合于 OLAP 场景。
  • MOT 是内存引擎默认使用的缓冲区,openGauss 的 MOT 内存引擎的索引结构以及整体的数据组织都是基于 Masstree 模型实现的,其乐观并发控制和高效的缓存块利用率使得 openGauss 可以充分发挥内存的性能,同时,在确保高性能的前提下,内存引擎有着与 openGauss 原有机制相兼容的并行持久化和检查点能力(CALC 逻辑一致性异步检查点),确保数据的永久存储,适合于高吞吐低时延的业务处理场景。

SQL 执行器在共享缓冲区中对数据页的操作会被记录到 WAL buffer 中,当客户端发起事务的 commit 请求时,WAL buffer 的内容将被 WalWriter 线程刷新到磁盘并保存在 WAL 日志文件中,确保那些已提交的事务都被永久记录,不会丢失。 但需要注意的是,当 walwriter 的写操作跟不上时数据库实际的需求时,常规后端线程仍然有权进行 WAL 日志的刷盘动作。这意味着 WALWriter 不是一个必要的进程,可以在请求时快速关闭。

  • maintenance_work_mem 一般是在 openGauss 执行维护性操作时使用,如:VACUUM、CREATE INDEX、ALTER TABLE ADD FOREIGN KEY 等操作,maintenance_work_mem 内存区域的大小决定了维护操作的执行效率。
  • temp_buffer 是每个数据库会话使用的 LOCAL 临时缓冲区,主要缓存会话所访问的临时表数据。需要注意的是,openGauss 支持全局临时表和会话级临时表,全局临时表的表定义是全局的,而临时表的数据是各个会话私有的。
  • work_mem 是事务执行内部排序或 Hash 表写入临时文件之前使用的内存缓冲区。

二、接下来我们再了解一下 openGauss 的后台辅助线程

线程名称 描述
jemalloc_bg_thd 管理并实现内存的动态分配
StatCollector 负责统计openGauss数据库的信息,包括:物理硬件资源使用信息、对象属性及使用信息、SQL运行信息、会话信息、锁信息、线程信息等,并且将这些收集到的统计信息保存在pgstat.stat文件中
Auditor 使用重定向的方式从管理线程、后台线程以及其他子线程获取审计数据,并保存在审计文件中
LWLockMonitor 负责检测轻量级锁(LWLock)产生的死锁,轻量级锁主要提供对共享内存的互斥访问控制,比如Clog buffer(事务提交状态缓存)、Shared buffers(数据页缓存)、Substran buffer(子事务缓存)等
sysLogger 使用重定向的方式捕获管理线程、后台线程以及其他子线程的stderr输出,并写入日志文件中
Jobworker JOB线程分为调度线程和工作线程。调度线程(JobScheduler)会根据pg_job表里面定义的JOB周期,对已经过期的JOB进行调用,由工作线程(Jobworker)执行实际的JOB任务
percentworker 根据percentile参数设置的值计算sql响应时间的百分比信息,目前percentile参数仅支持80和95
snapshotworker 收集snapshot信息,openGauss数据库的WDR报告依赖于snapshot
ashworker 统计历史活动会话相关信息
alarm openGauss的告警检测线程
清理线程(AutoVacLauncher+AutoVacWorker) AutoVacLauncher线程由Postmaster线程启动,它不断地将数据库需要做vacuum的对象信息保存在共享内存中,当表上被删除或更新的记录数超过设定的阈值时,会调用AutoVacWorker线程对表的存储空间执行回收清理工作
WalSender 运行在openGauss主备环境中主节点,发送预写日志给备节点
WalReceiver 运行在openGauss主备环境中备节点,接收预写日志记录
pagewriter 负责将脏页数据拷贝至双写(double-writer)区域并落盘,然后将脏页转发给bgwriter子线程进行数据下盘操作,如果发生数据页"折断"的问题,就会从双写空间里找到完整的数据页进行恢复
bgwriter 负责对共享缓冲区的脏页数据持续的进行刷盘操作,目的是让数据库线程在进行用户查询时可以很少或者几乎不等待写动作的发生,这样的机制同样也减少了检查点造成的性能下降
Checkpointer 周期性的发起数据库检查点,在这个检查点时刻,所有的数据文件都被更新,脏数据页也被刷新到磁盘,此刻数据库是一致的。openGauss支持全量检查点和增量检查点,增量检查点打开后会小批量的分阶段的滚筒式的去进行脏页刷盘

关于其他后台辅助线程的介绍,可以参考文章《浅聊 openGauss 逻辑架构》

三、Database 相关文件

目录名称 描述
base openGauss数据库对象默认存储在该目录,如默认的数据库postgres、用户创建的数据库及关联的表等对象
global 存储openGauss共享的系统表或者说是共享的数据字典表
pg_tblspc 即是openGauss的表空间目录,里面存储openGauss定义的表空间的目录软链接,这些软链接指向openGauss数据库表空间文件的实际存储目录
pg_xlog 存储openGauss数据库的WAL日志文件
pg_clog 存储openGauss数据库事务提交状态信息
pg_csnlog 存储openGauss数据库的快照信息,openGauss事务启动时会创建一个CSN快照,在MVCC机制下,CSN作为openGauss的逻辑时间戳,模拟数据库内部的时序,用来判断其他事务对于当前事务是否可见
pg_twophase 存储两阶段事务提交信息,用来确保数据一致性
pg_serial 存储已提交的可序列化事务信息
pg_multixact 存储多事务状态信息,一般用于共享行级锁(shared row locks)

四、openGauss 配置相关文件

文件名称 描述
postgresql.conf openGauss的配置文件,在gaussmaster线程启动时会读取该文件,获取监听地址、服务端口、内存分配、功能设置等配置信息,并且根据该文件,在openGauss启动时创建共享内存和信号量池等
pg_hba.conf 基于主机的接入认证配置文件,主要保存鉴权信息(如:允许访问的数据库、用户、IP段、加密方式等)
pg_ident.conf 客户端认证的配置文件,主要保存用户映射信息,将主机操作系统的用户与openGauss数据库用户做映射
gaussdb.state 主要保存数据库当前的状态信息(如:主备HA的角色、rebuild进度及原因、sync状态、LSN信息等)

五、openGauss 其他重要文件

目录名称 描述
Archived WAL openGauss数据库WAL日志的归档目录,保存openGauss的历史WAL日志
pg_audit 存储openGauss数据库的审计日志文件
pg_replslot 存储openGauss数据库的复制事务槽数据
pg_llog 保存逻辑复制时的状态数据

关于 openGauss 体系架构就为大家介绍到这里,鉴于笔者并非 openGauss 内核开发人员,这里仅从 DBA 的角度粗浅的对 openGauss 数据库体系架构为大家做一个简单介绍,若文章有描述错误之处,欢迎指正。将及时修正以免误导大家。

文末寄语:

openGauss 开源至今已将近 1 年,合作伙伴和广大数据库爱好者的努力使得 openGauss 数据库得以快速健康地向前发展,openGauss 目前已发布至 2.0.0 版本,按照发布计划应该会在 6 月 31 日发布新的版本,欢迎各位小伙伴关注。 在个人的工作中,偶尔有小伙伴反馈 openGauss 有些不足之处使其对国产数据库失去了信心,为国产数据库的发展前景画了一个问号。这里我想阐述一下个人观点: Oracle 起源于 1977 年,MySQL 起源于 1979 年,SQL Server1987 年,那么我们国产数据库呢? 根据墨天轮发布的 2021 年 6 月份《国产数据库流行度排行榜》,前三甲国产数据库中,2016 年 12 月 TiDB RC1 发布,2011 年 OceanBase 0.1 发布,2017 年 PolarDB 发布。而国产数据库真正的发力时间点个人认为应该是在 2020 年,从 2020 年至今,国产数据库可谓是百家争鸣,无论是开源建设、技术发展还是生态建设都处于突飞猛进的状态。从时间上看,国产数据库真正的发展时间比国外主流数据库晚将近 40 载,在一个良好的数据库技术生态环境下,经历 40 载的光阴打磨,形成一款优秀的数据库软件是理所当然。所以,综合起来看,以 Oracle 为代表的数据库无论是生态建设还是技术成熟度都比国产数据库有一定的先天优势。 但当今的国产数据库发展现状已经不可同日而语,IT 从业人员基本也都意识到核心 IT 技术国产化的重要性。无论是传统数据库厂商、互联网厂商还是其他 IT 厂商等等诸多厂商都在做属于自己的数据库产品,仅墨天轮《国产数据库流行度排行榜》所统计的数据库就多达 130+种,而且这些数据库的技术起点已经处于一个较高且成熟的水平。在互联网、金融、政府、能源、电信等诸多核心行业中都在不断地尝试国产数据库在核心业务场景下的使用。 为了打造一个更好的国产数据库技术生态,openGauss、TiDB、OceanBase 等优秀的数据库源代码已对外开放,合作伙伴可以根据源代码,发行属于自己的商业版本数据库,促进国产数据库的生态建设。 同时,我国的各大高等院校也增加了大量国产数据库的课程内容,为国产数据库后续的人才建设提供了有力保障,这些是国产数据库的未来。 所以,理性且客观的看,国产数据库和全球主流数据库存在些许差距,但国产数据库的发展环境已经不可同日而语,生态建设、人才发展、技术演进正在紧锣密鼓的向前"奔跑",对国产数据库未来的发展应该有绝对的信心和自信,国产数据库与全球主流数据库的差距正在迅速缩小,至于什么时候与全球主流数据库比肩甚至超越,我相信只是时间问题,但不会太久。

相关推荐
十叶知秋7 分钟前
【jmeter】jmeter的线程组功能的详细介绍
数据库·jmeter·性能测试
W Y20 分钟前
【架构-37】Spark和Flink
架构·flink·spark
Gemini199541 分钟前
分布式和微服务的区别
分布式·微服务·架构
瓜牛_gn2 小时前
mysql特性
数据库·mysql
奶糖趣多多3 小时前
Redis知识点
数据库·redis·缓存
CoderIsArt4 小时前
Redis的三种模式:主从模式,哨兵与集群模式
数据库·redis·缓存
师太,答应老衲吧6 小时前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
Channing Lewis7 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
毕业设计制作和分享8 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
ketil278 小时前
Redis - String 字符串
数据库·redis·缓存