前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(1)

【连载】如何掌握openGauss数据库核心技术?秘诀三:拿捏存储技术(1)

作者头像
数据和云
发布2021-12-08 17:55:31
5290
发布2021-12-08 17:55:31
举报
文章被收录于专栏:数据和云数据和云

前文回顾:

  1. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(1)
  2. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(2)
  3. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(3
  4. 如何掌握openGauss数据库核心技术?秘诀一:拿捏SQL引擎(4)
  5. 如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(1
  6. 如何掌握openGauss数据库核心技术?秘诀二:拿捏执行器技术(2)

目录

  • openGauss数据库SQL引擎
  • openGauss数据库执行器技术
  • openGauss存储技术

一、openGauss存储概览

二、openGauss行存储引擎

Ⅰ、行存储引擎总体架构

Ⅱ、行存储的基本模型与页面组织结构

Ⅲ、行存储的多版本管理以及DML操作

Ⅳ、基于CSN的MVCC机制

Ⅴ、行存储的空间回收

Ⅵ、行存储的共享缓存管理

Ⅶ、并行日志系统设计

Ⅷ、持久化及故障恢复系统设计

三、openGauss列存储引擎

四、openGauss内存引擎

  • openGauss事务机制
  • openGauss数据库安全

openGauss存储技术

OLTP(联机事务处理系统)以高并发读写为主,数据实时性要求非常高,数据以行的形式组织,最适合面向外存设计的行存储引擎。随着内存逐渐变大,服务器上万亿字节(TB)大小的内存已经很常见,内存引擎面向大内存而设计,提高系统的吞吐量和降低业务时延。OLAP联机数据分析处理系统主要面向大数据量分析场景,对数据存储效率、复杂计算效率的要求非常高。列存储引擎可以提供很高的压缩比,同时面向列的计算,CPU指令高速缓存和数据高速缓存的命中率比较高,计算性能比较好,按需读取列数据,大大减少不必要的磁盘读取,非常适合数据分析场景。openGauss整个系统设计是可插拔、自组装的,并支持多个存储引擎来满足不同场景的业务诉求,目前支持行存储引擎、列存储引擎和内存引擎。

一.openGauss存储概览

早期计算机程序通过文件系统管理数据,到了20世纪60年代这种方式就开始不能满足数据管理要求了,用户逐渐对数据并发写入的完整性、高效的检索提出更高的要求。由于机械磁盘的随机读写性能问题,从20世纪80年代开始,大多数数据库一直在围绕着减少随机读写磁盘进行设计。主要思路是把对数据页面的随机写盘转化为对WAL(Write Ahead Log)的顺序写盘,WAL持久化完成,事务就算提交成功,数据页面异步将数据刷新到磁盘上。但是随着内存容量变大、保电内存、非易失性内存的发展,以及SSD(Solid State Disk,固态硬盘)技术逐渐的成熟,IO性能得到极大提高,经历了几十年发展的存储引擎需要调整架构来发挥SSD的性能和充分利用大内存计算的优势。随着互联网、移动互联网的发展,数据量剧增,业务场景多样化,一套固定不变的存储引擎不可能满足所有应用场景的诉求。因此现在的DBMS需要设计支持多种存储引擎,根据业务场景来选择合适的存储模型。

1. 数据库存储引擎要解决的问题
数据库存储引擎要解决的问题如下:
(1) 存储的数据必须要保证:原子性(A)、一致性(C)、隔离性(I)、持久性(D)。
(2) 高并发读写,高性能。
(3) 充分发挥硬件的性能,解决数据的高效存储和检索能力。
2. openGauss存储引擎概述

openGauss整个系统设计是可插拔、自组装的,支持多个存储引擎来满足不同场景的业务诉求。当前openGauss存储引擎有以下3种:

(1) 行存储引擎,主要面向OLTP场景设计,例如订货、发货、银行交易系统。

(2) 列存储引擎,主要面向OLAP场景设计,例如数据统计报表分析。

(3) 内存引擎,主要面向极致性能场景设计,例如银行风控场景。

创建表的时候可以指定为行存储引擎表、列存引擎表、内存引擎表,支持一个事务里包含对三种引擎表的DML操作,可以保证事务的ACID性质。

二.openGauss行存储引擎

openGauss行存储引擎采用原地更新(in-place update)设计,支持MVCC(Multi-Version Concurrency Control,多版本并发控制),同时支持本地存储和存储、计算分离部署方式。行存储引擎的特点是支持高并发读写,时延小,适合OLTP交易类业务场景。

行存储引擎总体架构

01

openGauss的行存储引擎在设计上支持MVCC,采用集中式垃圾版本回收机制,可以提供OLTP业务系统的高并发读写要求,支持存储计算分离架构、存储层异步回放日志。行存储引擎架构如图1所示。

图1 行存储引擎架构

注:数据页面缓冲池中缓存数据页面,在数据页面里面存放元组以及元组的历史版本集中管理,使用垃圾清理(Vacuum)线程进行定期的空间回收。

行存储引擎的关键技术有:

(1) 基于事务ID以及行号(ctid)的多版本管理。

(2) 基于CSN(Commit Sequence Number,待提交事务的序列号,它是一个64位递增无符号数)的多版本可见性判断以及MVCC并发控制机制。

(3) 基于大内存设计的缓冲区管理。

(4) 平滑无性能波动的增量检查点(checkpoint)。

(5) 基于并行回放的快速故障实例恢复。

主要模块如下(如图2所示):

(1) 存储访问接口

(2) 索引

(3) 事务管理

(4) 锁管理

(5) 表和分区存储

(6) 页面缓存管理

(7) 表空间管理

(8) Redo日志管理

(9) 文件访问接口

图2 行存储主要模块

行存储的基本模型与页面组织结构

02

行存储的Tuple结构以及页面组织,是行存储DML实现、可见性判断以及行存各种功能与管理机制的基石。

由于行存储是基于磁盘的存储引擎,因此在存储格式的设计中遵从段页式设计,存储结构需要以页面(page)作为单位,以方便与操作系统内核以及文件系统的接口进行交互。也是由于这个原因,页面的大小需要和目标系统中一个block(块)的大小对齐。在比较通用的linux内核中,页面大小默认一般为8192(8k)。一个基本的Heap(堆)页面如图3所示:

图3 Heap页面示意图

页面开头的位置为整个页面的头部信息,记录了这个页面的公用信息以及一些关键标识。

line_pointer被放置与Header后面,并向页面尾部扩展。line_pointer为指向tuple实际数据的一个指针,类似于sentinel(行指针)的作用。

这里需要一提的是,每个Tuple在系统中的唯一标识,ItemPointer,也被称为CTID,存储的是这一行所在的block number(即页面号)以及其对应的line_pointer的offset(即这个页面中第几个line_pointer)。这样由一个系统内记录的CTID,可以快速定位到这个Tuple的line_pointer,也就可以根据line_pointer的指针快速定位到Tuple的实际数据。

line_pointer的必要性也可以比较容易的总结出来。由于Tuple的数据内容本身可以是变长的,因此如果需要找到一个在页面中间的Tuple,则需要按序遍历页面结构;而line_pointer结构本身为定长,因此可以直接以常数的复杂度找到数据所在内存位置。Line_pointer sentinel的效果也十分明显:line_pointer的存在使得Tuple的对应改动局限于页面内部,而保持全局标识CTID不发生变化;如果没line_pointer,行更新需要连带更新的元信息、索引以及系统各处信息的复杂度就不言而喻了。

被line_pointer指向的行记录本身,则是从页面结尾开始向页面头部延展,这样避免的页面填充过程中可能出现的数据移动以及空间浪费。

页面头部的Header中储存了如下信息:

(1) Pd_lsn为最后一次改动此页面事务写下的WAL(系统中一般称为transaction log,简称xlog)的下一位,被xlog机制以及checkpoint机制所使用。

(2) Pd_checksum为页面中的checksum,为了检查页面的完整性和一致性使用。

(3) Pd_flags是此页面的标识位,可以让上层对此页面进行处理的接口快速识别此页面的一些特征,比如页面是否有空行/页面是否写满、页面是否已经对所有事务全部可见、页面是否被压缩等。

(4) Pd_lower和pd_upper是指向页面空闲空间起止的指针,即pd_lower指向下一个line_pointer的位置,而pd_upper指向下一个行记录数据填充的位置,这样既可以快速进行页面的填充修改,也可以方便计算页面的空闲空间。

(5) Pd_special指针用于记录一些特殊的存储管理方式以及接口所需的内存区域。

(6) pd_prune_xid记录上一次对此页面进行清理的xid。

(7) pd_xid_base以及pd_multi_base为这个页面上xid的base,即该页面上所有的记录的xid都由页面自身记录的xid(32位)与base(32位)计算得到,是64位xid的实现方式。

每个记录本身(上文Tuple的数据部分),则是数据库中最基本的数据存储单位,其自身的结构以及记录的信息也是系统中存储方式、DML、事务ACID的关键。如图4所示:

图4 数据部分结构

(1) Xmin是最初始的TransactionID(事务ID,简称XID),即插入此条记录的事务ID。

(2) Xmax是删除或更新此条记录的XID。如果此记录未被更改或删除,那么Xmax为0。

(3) T_cid记录的是command id,用于一个事务内部多步操作的一种记录与跟踪。

(4) T_ctid记录了此条记录的CTID值,或者是更新版本的CTID值。这个会在后面展开DML时讲到。

(5) 两个infomask是事务以及存储数据状态的标识位,用于快速判断。

Xmin、xmax两个事务ID、结合其transaction ID(事务ID)映射的Clog(提交日志)、CSN Log,一同构成了可见性判断的核心关键要素.

未完待续.......

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据和云 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 数据库存储引擎要解决的问题
  • 数据库存储引擎要解决的问题如下:
  • (1) 存储的数据必须要保证:原子性(A)、一致性(C)、隔离性(I)、持久性(D)。
  • (2) 高并发读写,高性能。
  • (3) 充分发挥硬件的性能,解决数据的高效存储和检索能力。
  • 2. openGauss存储引擎概述
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档