数据库核心技术

面向应用开发的基本功能

  • 支持标准SQL

    openGauss数据库支持标准的SQL。SQL标准是一个国际性的标准,定期会进行更新。SQL标准的定义分成核心特性以及可选特性,绝大部分的数据库都没有100%支撑SQL标准。遗憾的是,SQL特性的构筑成为了数据库厂商吸引用户和提高应用迁移成本的手段,新的SQL特性在厂商之间差异越来越大,目前还没有机构来进行权威的SQL标准度的测试。

    openGauss数据库支持SQL:2011大部分的核心特性,同时还支持部分的可选特性,具体的特性列表可以参考《SQL参考》中“SQL语言结构和语法>SQL语法”章节。

    标准SQL的引入为所有的数据库厂商提供统一的SQL界面,减少使用者的学习成本和应用openGauss程序的迁移代价。

  • 支持标准开发接口

    提供业界标准的JDBC接口,保证用户业务快速迁移至openGauss。

    目前支持标准的JDBC 4.0接口,JDBC无平台差异。

  • 支持多存储引擎

    openGauss基于统一的事务机制,统一的日志系统,统一的并发控制系统,统一的元信息,统一缓存管理提供Table Access Method接口,支持不同的存储引擎。目前支持Astore和Ustore存储引擎。

  • 事务支持

    事务支持指的就是系统提供事务的能力,支持全局事务的ACID,保证事务的原子性、一致性、隔离性和持久性。

    事务支持及数据一致性保证是绝大多数数据库的基本功能,只有支持了事务,才能满足事务化的应用需求。

    • A:Atomicity 原子性

      整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节。

    • C:Consistency 一致性

      事务必须始终保持系统处于一致的状态,不管在任何给定的时间并发事务的数量。

    • I: IOsolation 隔离性

      隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。

    • D:Durability 持久性

      在事务完成以后,该事务对数据库所作的更改便持久的保存在数据库之中,并不会被回滚。

    支持事务的默认隔离级别是读已提交。保证不会读到脏数据。

    事务分为单语句事务和事务块,相关基础接口:

    • Start transaction:事务开启
    • Commit:事务提交
    • Rollback:事务回滚

    另有Set transaction可设置隔离级别、读写模式或可推迟模式。详细语法参见《SQL参考》。

  • 函数及存储过程支持

    函数是数据库中的一种重要对象,主要功能将用户特定功能的SQL语句集进行封装,并方便调用。

    存储过程是SQL、PL/SQL的组合。存储过程可以使执行商业规则的代码从应用程序中移动到数据库。从而,代码存储一次能够被多个程序使用。

    1. 允许客户模块化程序设计,对SQL语句集进行封装,调用方便。
    2. 存储过程会进行编译缓存,可以提升用户执行SQL语句集的速度。
    3. 系统管理员通过对执行某一存储过程的权限进行限制,能够实现对相应数据访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
    4. 为了处理SQL语句,存储过程进程分配一段内存区域来保存上下文联系。游标是指向上下文区域的句柄或指针。借助游标,存储过程可以控制上下文区域的变化。
    5. 支持6种异常信息级别方便客户对存储过程进行调试。支持存储过程调试,存储过程调试是一种调试手段,可以在存储过程开发中,一步一步跟踪存储过程执行的流程,根据变量的值,找到错误的原因或者程序的bug,提高问题定位效率。支持设置断点和单步调试。

    openGauss支持SQL标准中的函数及存储过程,增强了存储过程的易用性。存储过程具体的使用方式可以参考《SQL参考》。

  • PG接口兼容

    兼容PSQL客户端,兼容PostgreSQL标准接口。

  • 支持SQL hint

    支持SQL hint影响执行计划生成、提升SQL查询性能。

    Plan Hint为用户提供了直接影响执行计划生成的手段,用户可以通过指定join顺序,join、stream、scan方法,指定结果行数,等多个手段来进行执行计划的调优,以提升查询的性能。

  • Copy接口支持容错机制

    openGauss提供用户封装好的Copy错误表创建函数,并允许用户在使用Copy From指令时指定容错选项,使得Copy From语句在执行过程中部分解析、数据格式、字符集等相关的报错不会报错中断事务、而是被记录至错误表中,使得在Copy From的目标文件即使有少量数据错误也可以完成入库操作。用户随后可以在错误表中对相关的错误进行定位以及进一步排查。

高性能

CBO优化器

openGauss优化器是典型的基于代价的优化 (Cost-Based Optimization,简称CBO)。在这种优化器模型下,数据库根据表的元组数、字段宽度、NULL记录比率、distinct值、MCV值、HB值等表的特征值,以及一定的代价计算模型,计算出每一个执行步骤的不同执行方式的输出元组数和执行代价(cost),进而选出整体执行代价最小/首元组返回代价最小的执行方式进行执行。

CBO优化器能够在众多计划中依据代价选出最高效的执行计划,最大限度的满足客户业务要求。

行列混合存储

openGauss支持行存储和列存储两种存储模型,用户可以根据应用场景,建表的时候选择行存储还是列存储表。

一般情况下,如果表的字段比较多(大宽表),查询中涉及到的列不很多的情况下,适合列存储。如果表的字段个数比较少,查询大部分字段,那么选择行存储比较好。

列存储方式如图1所示。

图 1 列存储示意图
数据库核心技术 - 图1

在大宽表、数据量比较大的场景中,查询经常关注某些列,行存储引擎查询性能比较差。例如气象局的场景,单表有200~800个列,查询经常访问10个列,在类似这样的场景下,向量化执行技术和列存储引擎可以极大的提升性能和减少存储空间。

行存表和列存表各有优劣,建议根据实际情况选择。

  • 行存表

    默认创建表的类型。数据按行进行存储,即一行数据紧挨着存储。行存表支持完整的增删改查。适用于对数据需要经常更新的场景。

  • 列存表

    数据按列进行存储,即一列所有数据紧挨着存储。单列查询IO小,比行存表占用更少的存储空间。适合数据批量插入、更新较少和以查询为主统计分析类的场景。列存表不适合点查询,insert插入单条记录性能差。

行存表和列存表的选择原则如下:

  • 更新频繁程度

    数据如果频繁更新,选择行存表。

  • 插入频繁程度

    频繁的少量插入,选择行存表。一次插入大批量数据,选择列存表。

  • 表的列数

    表的列数很多,选择列存表。

  • 查询的列数

    如果每次查询时,只涉及了表的少数(<50%总列数)几个列,选择列存表。

  • 压缩率

    列存表比行存表压缩率高。但高压缩率会消耗更多的CPU资源。

In-place update存储

新增的In-place update存储引擎很好的解决了Append update存储引擎空间膨胀,元组较大的劣势,高效回滚段的设计是In-place update存储引擎的基础。

Xlog无锁刷新与并行Page回放

图 2 Xlog lock less Design
数据库核心技术 - 图2

本特性对WalInsertLock进行优化,利用LSN(Log Sequence Number)及LRC(Log Record Count)记录了每个backend的拷贝进度,取消WalInsertLock机制。在backend将日志拷贝至WalBuffer时,不用对WalInsertLock进行争抢,可直接进行日志拷贝操作。并利用专用的WalWriter写日志线程,不需要backend线程自身来保证xlog的Flush。通过以上优化,取消WalInsertLock争抢及WalWriter专用磁盘写入线程,在保持原有XLog功能不变的基础上,可进一步提升系统性能。针对Ustore Inplace update WAL log写入,Ustore DML operation并行回放分发进行优化。通过利用Prefix和suffix来减少update WAL log的写入。通过把回放线程分多个类型来解决Ustore DML WAL大多都是多页面回放问题。同时把Ustore的数据页面回放分为按照blkno去分发里更好的提高并行回放的并行程度。

自适应压缩

当前主流数据库通常都会采用数据压缩技术。数据类型不同,适用于它的压缩算法不同。对于相同类型的数据,其数据特征不同,采用不同的压缩算法达到的效果也不相同。自适用压缩正是从数据类型和数据特征出发,采用相应的压缩算法,实现了良好的压缩比、快速的入库性能以及良好的查询性能。

数据入库和频繁的海量数据查询是用户的主要应用场景。 在数据入库场景中,自适应压缩可以大幅度地减少数据量,成倍提高IO操作效率,将数据簇集存储,从而获得快速的入库性能。当用户进行数据查询时,少量的IO操作和快速的数据解压可以加快数据获取的速率,从而在更短的时间内得到查询结果。

目前,数据库已实现了RLE、DELTA、BYTEPACK/BITPACK、LZ4、ZLIB、LOCAL DICTIONARY等多种压缩算法。数据库支持的数据类型与压缩算法的映射关系如下表所示。

-

RLE

DELTA

BITPACK/BYTEPACK

LZ4

ZLIB

LOCAL DICTIONARY

Smallint/int/bigint/Oid

Decimal/real/double

Money/time/date/

timestamp

-

Tinterval/interval/Time with time zone/

-

-

-

-

-

Numeric/char/varchar/text/nvarchar2

以及其他支持数据类型

例如,支持类手机号字符串的大整数压缩、支持numeric类型的大整数压缩、支持对压缩算法进行不同压缩水平的调整。

分区

在openGauss系统中,数据分区是在一个实例内部按照用户指定的策略对数据做进一步的水平分表,将表按照指定范围划分为多个数据互不重叠的部分。

对于大多数用户使用场景,分区表和普通表相比具有以下优点:

  • 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索效率。
  • 增强可用性:如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。
  • 方便维护:如果分区表的某个分区出现故障,需要修复数据,只修复该分区即可。
  • 均衡I/O:可以把不同的分区映射到不同的磁盘以平衡I/O,改善整个系统性能。

目前openGauss数据库支持的分区表为范围分区表、列表分区表、哈希分区表。

  • 范围分区表:将数据基于范围映射到每一个分区,这个范围是由创建分区表时指定的分区键决定的。这种分区方式是最为常用的。

    范围分区功能,即根据表的一列或者多列,将要插入表的记录分为若干个范围(这些范围在不同的分区里没有重叠),然后为每个范围创建一个分区,用来存储相应的数据。

  • 列表分区表:将数据基于各个分区内包含的键值映射到每一个分区,分区包含的键值在创建分区时指定。

    列表分区功能,即根据表的一列,将要插入表的记录中出现的键值分为若干个列表(这些列表在不同的分区里没有重叠),然后为每个列表创建一个分区,用来存储相应的数据。

  • 哈希分区表:将数据通过哈希映射到每一个分区,每一个分区中存储了具有相同哈希值的记录。

    哈希分区功能,即根据表的一列,通过内部哈希算法将要插入表的记录划分到对应的分区中。

用户在CREATE TABLE时增加PARTITION参数,即表示针对此表应用数据分区功能。

用户可以在实际使用中根据需要调整建表时的分区键,使每次查询结果尽可能存储在相同或者最少的分区内(称为“分区剪枝”),通过获取连续I/O大幅度提升查询性能。

实际业务中,时间经常被作为查询对象的过滤条件。因此,用户可考虑选择时间列为分区键,键值范围可根据总数据量、一次查询数据量调整。

SQL by pass

在典型的OLTP场景中,简单查询占了很大一部分比例。这种查询的特征是只涉及单表和简单表达式的查询,因此为了加速这类查询,提出了SQL-BY-PASS框架,在parse层对这类查询做简单的模式判别后,进入到特殊的执行路径里,跳过经典的执行器执行框架,包括算子的初始化与执行、表达式与投影等经典框架,直接重写一套简洁的执行路径,并且直接调用存储接口,这样可以大大加速简单查询的执行速度。

鲲鹏NUMA架构优化

鲲鹏NUMA架构优化图如下。

图 3 鲲鹏NUMA架构优化图
数据库核心技术 - 图3

  1. openGauss根据鲲鹏处理器的多核NUMA架构特点,进行针对性一系列NUMA架构相关优化,一方面尽量减少跨核内存访问的时延问题,另一方面充分发挥鲲鹏多核算力优势,所提供的关键技术包括重做日志批插,热点数据NUMA分布,CLog分区等,大幅提升TP系统的处理性能。
  2. openGauss基于鲲鹏芯片所使用的ARMv8.1架构,利用LSE扩展指令集实现高效的原子操作,有效提升CPU利用率,从而提升多线程间同步性能,XLog写入性能等。
  3. openGauss基于鲲鹏芯片提供的更宽的L3缓存cacheline,针对热点数据访问进行优化,有效提高缓存访问命中率,降低Cache缓存一致性维护开销,大幅提升系统整体的数据访问性能。

线程池高并发

在OLTP领域中,数据库需要处理大量的客户端连接。因此,高并发场景的处理能力是数据库的重要能力之一。

对于外部连接最简单的处理模式是per-thread-per-connection模式,即来一个用户连接产生一个线程。这个模式好处是架构上处理简单,但是高并发下,由于线程太多,线程切换和数据库轻量级锁区域的冲突过大导致性能急剧下降,使得系统性能(吞吐量)严重下降,无法满足用户性能的SLA。

因此,需要通过线程资源池化复用的技术来解决该问题。线程池技术的整体设计思想是线程资源池化、并且在不同连接之间复用。系统在启动之后会根据当前核数或者用户配置启动固定一批数量的工作线程,一个工作线程会服务一到多个连接session,这样把session和thread进行了解耦。因为工作线程数是固定的,因此在高并发下不会导致线程的频繁切换,而由数据库层来进行session的调度管理。

并行查询

openGauss的SMP并行技术是一种利用计算机多核CPU架构来实现多线程并行计算,以充分利用CPU资源来提高查询性能的技术。在复杂查询场景中,单个查询的执行较长,系统并发度低,通过SMP并行执行技术实现算子级的并行,能够有效减少查询执行时间,提升查询性能及资源利用率。SMP并行技术的整体实现思想是对于能够并行的查询算子,将数据分片,启动若干个工作线程分别计算,最后将结果汇总,返回前端。SMP并行执行增加数据交互算子(Stream),实现多个工作线程之间的数据交互,确保查询的正确性,完成整体的查询。

高可用

主备机

为了保证故障的可恢复,需要将数据写多份,设置主备多个副本,通过日志进行数据同步,可以实现节点故障、停止后重启等情况下,openGauss能够保证故障之前的数据无丢失,满足ACID特性。主备环境可以支持主备和一主多备两种模式。主备模式下,备机需要重做日志,可以升主。在一主多备模式下,所有的备机都需要重做日志,都可以升主。主备主要用于一般可靠性的OLTP系统能够节省一定的存储资源。而一主多备提供更高的容灾能力,适合于更高可靠性事务处理的OLTP系统。

主备之间可以通过switchover进行角色切换,主机故障后可以通过failover对备机进行升主。

为保证failover的时间可控,可以开启日志流控功能,控制日志发往备机的速率,保证备机堆积的日志会在小于流控配置的目标时间内回放完。开启流控后因为发送给备机日志的速率被动态调整,从而整体的事务的性能会有相应的降低。

初始化安装或者备份恢复等场景中,需要根据主机重建备机的数据,此时需要build功能,将主机的数据和WAL日志发送到备机。主机故障后重新以备机的角色加入时,也需要build功能将其数据和日志与新主机拉齐。Build包含全量build和增量build,全量build要全部依赖主机数据进行重建,拷贝的数据量比较大,耗时比较长,而增量build只拷贝差异文件,拷贝的数据量比较小,耗时比较短。一般情况下,优先选择增量build来进行故障恢复,如果增量build失败,再继续执行全量build,直至故障恢复。

openGauss除了流复制主备双机外,还支持逻辑复制。在逻辑复制中把主库称为源端数据库,备库称为目标端数据库,源端数据库根据预先指定好的逻辑解析规则对WAL文件进行解析,把DML操作解析成一定的逻辑变化信息(标准SQL语句),源端数据库把标准SQL语句发给目标端数据库,目标端数据库收到后进行应用,从而实现数据同步。逻辑复制只有DML操作。逻辑复制可以实现跨版本复制,异构数据库复制,双写数据库复制,表级别复制。

数据库核心技术 - 图4 说明: 目前轻量版场景下,openGauss不支持一主多备模式。

逻辑备份

openGauss提供逻辑备份能力,可以将用户表的数据以通用的text或者csv格式备份到本地磁盘文件,并在同构/异构数据库中恢复该用户表的数据。

闪回恢复

利用回收站的闪回恢复删除的表。数据库的回收站功能类似于windows系统的回收站,将删除的表信息保存到回收站中。 利用MVCC机制闪回恢复到指定时间点或者SCN点。

极致RTO

极致RTO开关开启后,xlog日志回放建立多级流水线,提高并发度,提升日志回放速度。

当业务压力过大时,备机的回放速度跟不上主机的速度。在系统长时间的运行后,备机上会出现日志累积。当主机故障后,数据恢复需要很长时间,数据库不可用,严重影响系统可用性。开启极致RTO(Recovery Time Object,恢复时间目标),减少了主机故障后数据的恢复时间,提高了可用性。

逻辑复制

openGauss提供逻辑解码功能,将物理日志反解析为逻辑日志。通过DRS等逻辑复制工具将逻辑日志转化为SQL语句,到对端数据库回放,达到异构数据库同步数据的功能。目前支持openGauss数据库与MySQL数据库、Oracle数据库之间的单向、双向逻辑复制。DN通过物理日志反解析为逻辑日志,DRS等逻辑复制工具从DN抽取逻辑日志转换为SQL语句,到对端数据库(MySQL)回放。逻辑复制工具同时从MySQL数据库抽取逻辑日志,反解析为SQL语句之后回放至openGauss,达到异构数据库同步数据的目的。

发布订阅

发布订阅基于逻辑复制实现,其中有一个或者更多订阅者订阅一个发布者节点上的一个或者更多发布。订阅者从它们所订阅的发布拉取数据。实现集群间的数据实时同步。发布者上的更改会被实时发送给订阅者。订阅者以与发布者相同的顺序应用那些数据,这样在一个订阅中能够保证发布的事务一致性。这种数据复制的方法有时候也被称为事务性复制。

恢复到指定时间点(PITR)

时间点恢复(Point In Time Recovery)基本原理是通过基础热备 + WAL预写日志 + WAL归档日志进行备份恢复。重放WAL记录的时候可以在任意点停止重放,这样就有一个在任意时间的数据库一致的快照。即可以把数据库恢复到自开始备份以来的任意时刻的状态。openGauss在恢复时可以指定恢复的停止点位置为TID,时间和LSN。

可维护性

支持WDR诊断报告

WDR(Workload Diagnosis Report)基于两次不同时间点系统的性能快照数据, 生成这两个时间点之间的性能表现报表,用于诊断数据库内核的性能故障。

WDR性能快照数据存储在postgres库的snapshot schema下,默认的采集和保存策略为:

  • 每小时采集一个快照(wdr_snapshot_interval=1h)。
  • 保留8天(wdr_snapshot_retention_days=8)。

WDR主要依赖两个组件:

  • SNAPSHOT性能快照:性能快照可以配置成按一定时间间隔从内核采集一定量的性能数据,持久化在用户表空间。任何一个SNAPSHOT可以作为一个性能基线,其他SNAPSHOT与之比较的结果,可以分析出与基线的性能表现。
  • WDR Reporter:报表生成工具基于两个SNAPSHOT,分析系统总体性能表现,并能计算出更多项具体的性能指标在这两个时间段之间的变化量,生成SUMMARY 和DETAIL两个不同级别的性能数据。如表1表2所示。

表 1 SUMMARY级别诊断报告

诊断类别

描述

Database Stat

主要用于评估当前数据库上的负载,IO状况,负载和IO是衡量TP系统最最要的特性

包含当前连接到该数据库的session,提交、回滚的事务数,读取的磁盘块的数量,高速缓存中已经发现的磁盘块的次数,通过数据库查询返回、抓取、插入、更新、删除的行数,冲突、死锁发生的次数,临时文件的使用量,IO读写时间等

Load Profile

从时间,IO,事务,SQL几个维度评估当前系统负载的表现

包含作业运行elapse time、CPU time,事务日质量,逻辑和物理读的量,读写IO次数、大小,登入登出次数,SQL、事务执行量,SQL P85、P90响应时间等

Instance Efficiency Percentages

用于评估当前系统的缓存的效率。

主要包含数据库缓存命中率

Events

用于评估当前系统内核关键资源,关键事件的性能

主要包含数据库内核关键时间的发生次数,时间的等待时间

Wait Classes

用于评估当前系统关键事件类型的性能

主要包含数据内核在主要的等待事件的种类上的发布:STATUS、LWLOCK_EVENT、LOCK_EVENT、IO_EVENT

CPU

主要包含CPU在用户态、内核态、Wait IO、空闲状态下的时间发布

IO Profile

主要包含数据库Database IO次数、Database IO数据量、Redo IO次数、Redo IO量

Memory Statistics

包含最大进程内存、进程已经使用内存、最大共享内存、已经使用共享内存大小等

表 2 DETAIL 级别诊断报告

诊断类别

描述

Time Model

主要用于评估当前系统在时间维度的性能表现

包含系统在各个阶段上消耗的时间:内核时间、CPU时间、执行时间、解析时间、编译时间、查询重写时间、计划生成时间、网络时间、IO时间

SQL Statistics

主要用于SQL语句性能问题的诊断

包含归一化的SQL的性能指标在多个维度上的排序:Elapsed Time、CPU Time、Rows Returned、Tuples Reads、Executions、Physical Reads、Logical Reads。这些指标的种类包括:执行时间,执行次数、行活动、Cache IO等

Wait Events

主要用于系统关键资源,关键时间的详细性能诊断

包含所有关键事件在一段时间内的表现,主要是事件发生的次数,消耗的时间

Cache IO Stats

用于诊断用户表和索引的性能

包含所有用户表、索引上的文件读写,缓存命中

Utility status

用于诊断后端作业性能

包含页面操作,复制等后端操作的性能

Object stats

用于诊断数据库对象的性能

包含用户表、索引上的表、索引扫描活动,insert、update、delete活动,有效行数量,表维护操作的状态等

Configuration settings

用于判断配置是否有变更

包含当前所有配置参数的快照

应用价值:

  • WDR报表是长期性能问题最主要的诊断手段。基于SNAPSHOT的性能基线,从多维度做性能分析,能帮助DBA 掌握系统负载繁忙程度,各个组件的性能表现,性能瓶颈。
  • SNAPSHOT也是后续性能问题自诊断和自优化建议的重要数据来源。

慢SQL诊断

慢SQL能根据用户提供的执行时间阈值,记录所有超过阈值的执行完毕的作业信息。

历史慢SQL提供表和函数两种维度的查询接口,用户从接口中能查询到作业的执行计划,开始、结束执行时间,执行查询的语句,行活动,内核时间,CPU时间,执行时间,解析时间,编译时间,查询重写时间,计划生成时间,网络时间,IO时间,网络开销,锁开销等。所有信息都是脱敏的。

慢SQL提供给用户对于慢SQL诊断所需的详细信息,用户无需通过复现就能离线诊断特定慢SQL的性能问题。表和函数接口方便用户统计慢SQL指标,对接第三方平台。

数据库安全

访问控制

管理用户对数据库的访问控制权限,涵盖数据库系统权限和对象权限。

支持基于角色的访问控制机制,将角色和权限关联起来,通过将权限赋予给对应的角色,再将角色授予给用户,可实现用户访问控制权限管理。其中登录访问控制通过用户标识和认证技术来共同实现,而对象访问控制则基于用户在对象上的权限,通过对象权限检查实现对象访问控制。用户为相关的数据库用户分配完成任务所需要的最小权限从而将数据库使用风险降到最低。

支持三权分立权限访问控制模型,数据库角色可分为系统管理员、安全管理员和审计管理员。其中安全管理员负责创建和管理用户,系统管理员负责授予和撤销用户权限,审计管理员负责审计所有用户的行为。

默认情况下,使用基于角色的访问控制模型。客户可通过设置参数来选择是否开启三权分立控制模型。

控制权和访问权分离

针对系统管理员用户,实现表对象的控制权和访问权分离,提高普通用户数据安全性,限制管理员对象访问权限。

该特性适用于如下场景,即对于有多个业务部门的企业,各部门间使用不同的数据库用户进行业务操作,同时存在同级别的数据库维护部门使用数据库管理员进行运维操作,业务部门希望在未经授权的情况下,管理员用户只能对各部门的数据进行控制操作(DROP、ALTER、TRUNCATE),但是不能进行访问操作(INSERT、DELETE、UPDATE、SELECT、COPY)。即针对管理员用户,表对象的控制权和访问权分离,提高用户数据的安全性。

系统管理员可以在创建用户时指定INDEPENDENT属性,表示该用户为私有用户。针对该用户的对象,数据库管理员(包含初始用户和其他管理员用户)在未经其授权前,只能进行控制操作(DROP、ALTER、TRUNCATE),无权进行INSERT、DELETE、SELECT、UPDATE、COPY、GRANT、REVOKE、ALTER OWNER操作。

数据库内置角色权限管理

openGauss提供了一组默认角色,以gs_role_开头命名。它们提供对特定的、通常需要高权限的操作的访问,可以将这些角色GRANT给数据库内的其他用户或角色,让这些用户能够使用特定的功能。在授予这些角色时应当非常小心,以确保它们被用在需要的地方。表3描述了内置角色允许的权限范围:

表 1 内置角色权限说明

角色

权限描述

gs_role_copy_files

具有执行copy … to/from filename 的权限,但需要先打开GUC参数enable_copy_server_files。

gs_role_signal_backend

具有调用函数pg_cancel_backend、pg_terminate_backend和pg_terminate_session来取消或终止其他会话的权限,但不能操作属于初始用户和PERSISTENCE用户的会话。

gs_role_tablespace

具有创建表空间(tablespace)的权限。

gs_role_replication

具有调用逻辑复制相关函数的权限,例如kill_snapshot、pg_create_logical_replication_slot、pg_create_physical_replication_slot、pg_drop_replication_slot、pg_replication_slot_advance、pg_create_physical_replication_slot_extern、pg_logical_slot_get_changes、pg_logical_slot_peek_changes,pg_logical_slot_get_binary_changes、pg_logical_slot_peek_binary_changes。

gs_role_account_lock

具有加解锁用户的权限,但不能加解锁初始用户和PERSISTENCE用户。

gs_role_directory_create

具有执行创建directory对象的权限,但需要先打开GUC参数enable_access_server_directory。

gs_role_directory_drop

具有执行删除directory对象的权限,但需要先打开GUC参数enable_access_server_directory。

数据库加密认证

采用基于客户端/服务端(C/S)模式的客户端连接认证机制。

加密认证过程中采用单向Hash不可逆加密算法PBKDF2,可有效防止彩虹攻击。

创建用户所设置的口令被加密存储在系统表中。整个认证过程中口令加密存储和传输,通过计算相应的hash值并与服务端存储的值比较来进行正确性校验。

统一加密认证过程中的消息处理流程,可有效防止攻击者通过抓取报文猜解用户名或者口令的正确性。

数据库审计

审计日志记录用户对数据库的启停、连接、DDL、DML、DCL等操作。审计日志机制主要增强数据库系统对非法操作的追溯及举证能力。

用户可以通过参数配置对哪些语句或操作记录审计日志。

审计日志记录事件的时间、类型、执行结果、用户名、数据库、连接信息、数据库对象、数据库实例名称和端口号以及详细信息。支持按起止时间段查询审计日志,并根据记录的字段进行筛选。

数据库安全管理员可以利用这些日志信息,重现导致数据库现状的一系列事件,找出非法操作的用户、时间和内容等。

网络通信安全特性

支持通过SSL加密客户端和服务器之间的通信数据,保证客户的客户端与服务器通信安全。

采用TLS 1.2协议标准,并使用安全强度较高的加密算法套件,支持的加密算法套件如表2所示。

表 2 加密算法套件

OpenSSL套件名

IANA套件名

安全程度

ECDHE-RSA-AES128-GCM-SHA256

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

HIGH

ECDHE-RSA-AES256-GCM-SHA384

TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

HIGH

ECDHE-ECDSA-AES128-GCM-SHA256

TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256

HIGH

ECDHE-ECDSA-AES256-GCM-SHA384

TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384

HIGH

行级访问控制

行级访问控制特性将数据库访问粒度控制到数据表行级别,使数据库达到行级访问控制的能力。不同用户执行相同的SQL查询操作,按照行访问控制策略,读取到的结果可能是不同的。

用户可以在数据表创建行访问控制(Row Level Security)策略,该策略是指针对特定数据库用户、特定SQL操作生效的表达式。当数据库用户对数据表访问时,若SQL满足数据表特定的Row Level Security策略,在查询优化阶段将满足条件的表达式,按照属性(PERMISSIVE | RESTRICTIVE)类型,通过AND或OR方式拼接,应用到执行计划上。

行级访问控制的目的是控制表中行级数据可见性,通过在数据表上预定义Filter,在查询优化阶段将满足条件的表达式应用到执行计划上,影响最终的执行结果。当前行级访问控制支持的SQL语句包括SELECT,UPDATE,DELETE。

资源标签

资源标签(Resource Label)特性通过将数据库资源按照用户自定义的方式划分,实现资源分类管理的目的。管理员可以通过配置资源标签统一地为一组数据库资源进行安全策略的配置如审计或数据脱敏。

资源标签能够将数据库资源按照“特征”、“作用场景”等分组归类,对指定资源标签的管理操作即对标签范围下所有的数据库资源的管理操作,能够大大降低策略配置的复杂度和信息冗余度,提高管理效率。

当前资源标签所支持的数据库资源类型包括:SCHEMA、TABLE、COLUMN、VIEW、FUNCTION。

动态数据脱敏

为了在一定程度上限制非授权用户对隐私数据的窥探,可以利用动态数据脱敏(Dynamic Data Masking)特性保护用户隐私数据。在非授权用户访问配置了动态数据脱敏策略的数据时,数据库将返回脱敏后的数据而达到对隐私数据保护的目的。

管理员可以在数据列上创建动态数据脱敏策略,该策略指出针对特定用户场景应采取何种数据脱敏方式。在开启动态数据脱敏功能后,当用户访问敏感列数据时,系统将用户身份信息例如:访问IP、客户端工具、用户名来匹配相应的脱敏策略,在匹配成功后将根据脱敏策略对访问列的查询结果实施数据脱敏。

动态数据脱敏的目的是在不改变源数据的前提下,通过在脱敏策略上配置针对的用户场景(FILTER)、指定的敏感列标签(LABEL)和对应的脱敏方式(MASKING FUNCTION)来灵活地进行隐私数据保护。

统一审计

统一审计(Unified Auditing)利用策略和条件在数据库内部有选择地进行审计,管理员可以对数据库资源或资源标签统一地配置审计策略,从而达到简化管理、针对性地生成审计日志、减少审计日志冗余、提高管理效率的目的。

管理员可以定制化的为操作行为或数据库资源配置审计策略,该策略针对特定的用户场景、用户行为或数据库资源进行审计。在开启了统一审计功能后,当用户访问数据库时,系统将根据用户身份信息如:访问IP、客户端工具、用户名来匹配相应的统一审计策略,之后根据策略信息对用户行为按照访问资源(LABEL)和用户操作类型(DML | DDL)进行统一审计。

统一审计的目的是将现有的传统审计行为转变为针对性的跟踪审计行为,将目标之外的行为排除在审计之外,从而简化了管理,提高了数据库生成审计数据的安全性。

用户口令强度校验机制

为了加固客户账户和数据的安全,禁止设置过低强度的口令,当初始化数据库、创建用户、修改用户时需要指定密码。密码必须满足强度校验,否则会提示用户重新输入密码。

账户密码复杂度对用户密码大小写字母、数字、特殊字符的最少个数,最大最小长度,不能和用户名、用户名倒写相同,不能是弱口令等进行了限制,从而增强了用户账户的安全性。

其中弱口令指的是强度较低,容易被破解的密码,对于不同的用户或群体,弱口令的定义可能会有所区别,用户需要自己添加定制化的弱口令。

用户口令强度校验机制是否开启由参数password_policy控制,当该参数设置为1时表示采用密码复杂度校验,默认值为1。

数据加密存储

提供对插入数据进行加密存储。

为用户提供数据加解密接口,针对用户识别的敏感信息列使用加密函数,使数据加密后再存储在表内。

当用户需要对整张表进行加密存储处理时,则需要为每一列单独书写加密函数,不同的属性列可使用不同的入参。

当具有对应权限的用户需要查看具体数据时,可通过解密函数接口对相应的属性列进行解密处理。

账本数据库

为了防止数据库运维人员可能存在监守自盗、篡改数据库并擦除痕迹等行为,可以利用账本数据库特性来进行更加全面的审计和追溯历史。在修改防篡改用户表数据时,数据库会将修改行为记录至只可追加数据的历史表中,从而达到记录操作历史和操作溯源的能力。

账本数据库通过生成数据hash摘要的方式来保存和验证历史操作。账本指的是用户历史表和全局区块表,对于表级别数据修改操作,系统将操作信息以及hash摘要记录至全局区块表中,同时每个防篡改用户表对应一个用户历史表来记录行级数据变更的hash摘要。用户可以通过重新计算hash摘要、验证hash摘要一致等方式判断防篡改用户表是否被篡改。

账本中的每条记录代表一条已经发生了的既定操作事实,其内容只可追加不可修改,通过对防篡改用户表和相应历史表进行一致性校验可以实现对篡改行为的识别和追踪溯源。此外,账本数据库提供了防篡改用户表一致性校验接口、历史表恢复和归档接口以满足篡改识别、数据膨胀消减、历史数据修复归档等需求。