• [技术干货] GaussDB(DWS) 原理及作用
    一、GaussDB(DWS)简介GaussDB(DWS)是一款基于华为自主研发的数据库管理系统,适用于大规模数据处理和分析场景。作为一款面向企业级应用的数据库产品,GaussDB(DWS)在性能、可靠性、易用性等方面具有显著优势。二、关键技术特性2.1 存储引擎GaussDB(DWS)采用列式存储引擎,相较于传统的行式存储,列式存储在数据压缩和查询性能方面具有明显优势。它能够针对特定列进行高效压缩,减少 I/O 消耗,提高查询效率。2.2 计算引擎GaussDB(DWS)的计算引擎采用自适应的查询优化技术,能够根据实际数据分布和查询特点,自动选择最优的执行计划。此外,计算引擎还支持向量化和代码生成技术,提高 CPU 利用率和计算性能。2.3 分布式事务管理GaussDB(DWS)采用两阶段提交协议(2PC)和乐观并发控制(OCC)机制,保证分布式环境下的数据一致性和事务的原子性、一致性、隔离性和持久性。2.4 高可用与容灾能力GaussDB(DWS)通过多副本机制和故障自动切换技术,实现了系统的高可用性。即使单个节点出现故障,系统也能迅速恢复,保证业务连续性。同时,它支持跨地域的容灾部署,进一步增强了数据安全性。2.5 数据安全与隐私保护GaussDB(DWS)提供多层次的数据安全机制,包括数据加密、访问控制、审计和脱敏等功能,确保数据在存储、传输和处理过程中的安全性。2.6 弹性伸缩面对数据量的动态变化,GaussDB(DWS)支持弹性伸缩,可以根据业务需求自动或手动调整集群规模,既保证了资源的高效利用,也避免了因数据增长导致的性能瓶颈。2.7 智能优化借助于AI和机器学习技术,GaussDB(DWS)能够自动分析历史查询模式,预测并优化查询计划,实现智能化的资源分配和查询优化,从而提升整体系统性能。三、应用场景与价值3.1 大数据分析在金融、电信、电商等行业,GaussDB(DWS)能够高效处理海量数据,支持复杂的OLAP查询,助力企业快速进行市场分析、客户行为分析等,为决策提供数据支持。3.2 实时报表与BIGaussDB(DWS)支持实时查询功能,适用于对实时性要求较高的场景,如物联网、金融风控等。凭借其高速的查询响应能力,GaussDB(DWS)成为构建实时报表和BI分析系统的理想选择,帮助企业实时监控业务状况,及时发现并解决问题。3.3 数据湖分析GaussDB(DWS)可以作为数据仓库使用,支持企业构建统一的数据平台,实现数据资产的集中管理和分析。结合数据湖技术,GaussDB(DWS)可以作为数据湖上的高性能分析引擎,对原始数据进行深度挖掘,实现更广泛的数据价值发现。3.4 机器学习GaussDB(DWS)支持机器学习算法,可以为用户提供智能化的数据分析和预测服务。四、结语总而言之,GaussDB(DWS)凭借其强大的数据处理能力、高度的灵活性和卓越的扩展性,正在为众多行业提供强有力的数据分析支撑。随着大数据和AI技术的不断融合,GaussDB(DWS)无疑将在推动企业智能化转型的道路上发挥更加关键的作用。未来,期待它能在更多领域展现其技术魅力,引领数据仓库技术的新一轮变革
  • [技术解读] GaussDB关键技术原理|高可用:逻辑复制
    GaussDB关键技术原理|高可用:DCF&双集群容灾从DCF与双集群容灾技术两方面对GaussDB的高可用能力进行了介绍,本篇将从逻辑复制方面继续解读GaussDB高可用技术。3 逻辑复制逻辑复制属于数据复制服务(Data Replication Service,简称DRS)一种,是一种易用、稳定、高效的数据库迁移和数据库同步。逻辑复制由逻辑解码和数据复制两部分组成,逻辑解码输出以事务为单位组织的逻辑日志,业务或数据库中间件对逻辑日志进行解析回放并最终实现数据复制。逻辑复制对目标数据库的形态限制较少,支持异构数据库、同构异形数据库,且同步期间目标库可读可写。另一方面,相比数据迁移工具定期同步数据逻辑复制数据同步时延低,提供实时数据复制的能力。众所周知,在不同选型数据库或数据库不同版本间,通常在物理日志、数据存储格式等方面存在差异,差异导致无法在物理层面实现数据复制。逻辑复制解析事务物理日志(数据及其操作记录)抽取具有类SQL的逻辑日志,通过逻辑日志重放屏蔽源和目标数据库物理差异从而实现数据同步。例如 GaussDB 解析WAL日志,通过DRS工具转为SQL发送到 Oracle 执行,完成GaussDB和Oracle这种异构数据库之间数据备份,如图所示。端到端的逻辑复制分成三部分:解码源端事务物理日志从中抽取业务操作对应的逻辑日志。DRS工具将逻辑日志转换/变型成目标端支持的SQL/调用。目标端接收DRS转换的SQL/调用并高效执行实现数据复制。值的注意的是,逻辑复制不是“SQL”复制,而是复制SQL操作的结果。异构数据库的逻辑复制一般都通过SQL标准语法作为中间桥梁(共同理解的语言),从而实现异构数据库间的等价语义传递。物理复制和逻辑复制各有优劣,分别有其适用的业务场景。逻辑复制使用场景和优点主要体现在灵活、细粒度、双向、异构等,适用场景但不限于:关键数据备份(细粒度复制)、数据分发/合聚复制、异构数据在线迁移、大版本滚动升级、数据抢救找回、数据异地容灾等。但在低时延、低损耗、读写分离等一致性要求非常严格的场景,建议选择物理复制。对于逻辑复制特性,GaussDB聚焦于物理日志到逻辑日志的解码转换(提供CDC所需要的基础设施),提供多种逻辑日志格式以便于二次开发,以及提升逻辑解码和日志重放性能来降低复制时延,保证数据同步的时效性和一致性。如图所示,GaussDB针对异构数据库间逻辑复制(蓝色链路)仅提供“逻辑解码”基础能力,DRS等数据库中间件处理逻辑日志并适配目标数据库回放,协同构建完整的逻辑复制。而同构的GaussDB之间通过发布订阅(黄色链路)特性承载,消除逻辑日志中转和翻译等,实现更高效更低时延的逻辑复制。3.1 基本概念复制行标识(Replica ID)数据库复制技术进行数据同步时用于标识数据库中复制的行或记录的唯一标识符。该标识可以是一个自增数字、全局唯一的UUID或其他形式,例如:逻辑日志主键列集或者唯一索引列集。复制行标识的主要作用包括:数据一致性:通过复制行标识确保不同的数据库实例之间复制的行唯一性和一致性,避免数据冲突和重复复制。冲突解决:复制行标识定位冲突行,依据行不同内容识别正确的版本。同步跟踪:根据行标识确定哪些行已经被复制,哪些行还未被复制。GaussDB逻辑复制的行标识通过ALTER TABLE .. REPLICA IDENTITY指定四种复制行标识:DEFAULT记录主键列的旧值,没有主键则不记录。USING INDEX记录索引列的旧值,索引必须是全局唯一的、不可延迟的,并且索引列含有NOT NULL约束。FULL记录该行中所有列的旧值。NOTHING不记录有关旧行的信息。逻辑复制源逻辑复制源是逻辑复制中同步的数据库实例、库或表,通过解析和重放逻辑日志,将源数据库的数据变更复制到目标数据库。逻辑复制的源与目标之间可以是主从关系,也可以是多对多的关系;多对多关系意味着源和目标之间可以相互复制。通过给逻辑复制源赋予一个标识,重放设置逻辑日志来自的逻辑复制源标识,解码过滤重放物理日志的逻辑日志,从而避免循环无限复制。GaussDB逻辑复制源使用流程:pg_replication_origin_create()创建复制源。pg_replication_origin_session_setup()设置会话重放逻辑日志的复制源。逻辑解码指定启动选项only-local过滤重放会话的逻辑日志。补充日志解码补充日志(Supplemental Logging)并不是独立的一种日志,它是对重做记录中变更内容的补充,增加的信息量以满足逻辑解码的基本要求或增强功能。若缺少解码补充日志,逻辑解码将无法正常工作。补充日志通常有:行标识、版本信息、事务用户等。GaussDB通过GUC参数WAL_LEVEL=logical调整物理日志记录级别,配置系统记录解码补充日志(重启生效) 。同时,该参数生效时阻塞AUTO VACCUM提前回收系统表中逻辑解码依赖的旧版本对象信息(被删除行)。增量复制相对全量复制,增量复制仅仅处理全量后被修改的增量(插、删、改)数据。逻辑解码通过解析增量的物理日志提取逻辑操作,提供一套完整的全量和增量数据的衔接,保证逻辑复制的数据完整性。GaussDB创建逻辑复制槽用于新建一个逻辑解码任务,返回的查询快照可以用于构建解码相关的全量复制数据。3.2 逻辑解码逻辑解码是一项数据库技术,用于将数据库的事务日志解析为易于理解和处理的格式。它允许用户对数据库操作进行实时监控、数据变更跟踪和数据复制等应用。当启用逻辑解码时,GaussDB将每个事务的基本操作和解码辅助信息记录到事务日志中,并以一种结构化的方式存储。这些事务(物理)日志包含数据库中发生的所有数据变更的细节,包括插入、更新和删除等操作,同时包含了诸多用户理解不友好的数据库内部细节和特有实现。逻辑解码通过输出格式插件形式将这些事务日志解析为易于理解的格式,例如JSON或自定义二进制格式等多种更高级别的事件或操作,使得用户可以根据自身需求来解析和处理这些数据变更事件。物理日志和系统表对象元数据是逻辑解码的内容来源。逻辑解码从物理日志捕获用户表DML的变更记录,依据其中的物理存储标识(relfilenode)和记录时系统提交序号(CSN)到加载系统表对应时刻的对象元信息;继而将物理变更记录中强耦合的内部信息转换为用户可理解的表内容,生成和数据库实现无关的逻辑变更记录;最后重排和发送逻辑变更记录。如上图所示,逻辑解码实现涉及五大部分:(1)修改内核配置支持逻辑解码,设置捕获表复制行标识。(2)创建逻辑解码任务——逻辑复制槽。(3)生成用于逻辑解码的物理日志,阻塞回收系统表旧版本对象元数据。(4)启动逻辑解码从物理日志中抽取用户期望格式的逻辑日志。(5)重排汇总事务逻辑日志,以事务为单位按照提交顺序发送逻辑日志。GaussDB提供两种获取逻辑日志的接口:函数解码和流式解码。函数解码属于用户多次执行SQL拉取(PULL),SQL调用系统解码函数按照数据集的方式返回逻辑日志;流式解码不同于函数解码,内核持续不断的解码并PUSH逻辑日志,用户侧从数据流中不断接收逻辑日志。当前函数解码只支持串行解码,流式解码支持串行和并行解码;流式解码相对函数解码性能好时延低,更适用于实时同步的业务场景。当前JDBC驱动封装逻辑复制接口,流式解码流程大致如图所示:(1)复制业务或工具设定解码选项,通过JDBC封装接口启动内核逻辑解码,得到获取逻辑日志的数据流;(2)内核解析选项启动逻辑解码,处理存量物理日志并监测新日志产生,持续抽取逻辑日志并将其推送(PUSH)到数据流;(3)复制业务或工具从数据流中读取(readPending)逻辑日志进行处理或传递下游;(4)完成逻辑日志处理,复制业务或工具反馈(setFlushedLSN+forceUpdateStatus)内核来推进逻辑解码任务,后续启动解码将不再发送已处理的逻辑日志。注意:复制业务或工具若是提前反馈,内核推进了逻辑解码任务可能导致数据丢失;若是不反馈或者反馈周期较长,内核将出现物理日志堆积和系统表膨胀影响正常业务。3.3 备机解码逻辑解码读取物理日志消耗大量IO,逻辑日志生成消耗大量CPU,是一个资源密集型功能。考虑逻辑解码读取的物理日志和系统表,属于“读”操作不会产生数据变更,若在备机逻辑解码将会规避使用主机资源,降低对在线业务的影响。备机逻辑解码实现需要解决:(1)可以加载哪些物理日志解码;(2)解码是否可以读取系统表的历史版本元组;(3)推进逻辑复制槽的“写”如何实现。针对(1),虽然解码到事务提交才将事务逻辑日志返回给下游客户,但没有达成大多数派的物理日志不能参与逻辑解码。针对(2),逻辑解码依赖备机读功能,要求并行回放、极致RTO场景实现系统表的历史版本一致性访问。因此,备机解码加载的物理日志不超过ReplayLSN,保证解码日志所需的系统表可以正常读取。针对(3),备机解码首先根据客户反馈推进本地逻辑复制槽,然后创建内部到主机的连接使用复制advance协议推进逻辑复制槽,并通过物理日志实现与其他备机的逻辑复制槽同步。3.4 并行解码通过分析串行解码,逻辑解码三个主要步骤(读取日志、解码日志、发送日志)中的解码日志耗时占整个流程的70%以上,成为性能瓶颈。解码日志阶段属于CPU密集型业务,并行解码利用多线程并发技术,极大提高了逻辑解码吞吐量。并行解码基于日志粒度实现并行,如图所示,它包含三类线程:Reader线程读取物理日志,抽取业务DML操作以及解码必要内容构建LogicalLogChange变更,完成TOAST元组拼接并在主表的元组展开,轮询分发到Decoder线程的输入队列;Decoder线程从输入队列获取LogicalLogChange,根据日志版本内容加载数据表的元信息,将日志中物理数据转换成表名、列名、列数据外部形式等用户易理解的逻辑数据,传递转换后LogicalLog到输出队列;Sender线程按照DML日志生成顺序收集解码后的LogicalLog,根据事务ID桶排序进行汇总,以事务的提交顺序发送逻辑日志。并行解码解除了串行解码可见性判断逻辑需要构建活跃事务链表快照的依赖,基于CSN轻量化可见性判断逻辑极大简化了并行解码元数据加载。并行解码Reader和Decoder线程过程中访问系统表加载并缓存解码元数据;由于业务DDL引起元数据发生变更,Reader线程在DDL日志或事务结束时失效本地相应缓存,并将失效消息加入Decoder线程输入队列,广播通知Decoder线程失效缓存。3.5 一致性解码事务CSN改造优化快照获取消除gtm瓶颈,GaussDB对业务可见性的事务一致性序CommitCSN。为保证基于逻辑复制的备机数据对业务可见性和主机一致,逻辑解码提供基于事务CommitCSN有序发送逻辑日志,并根据下游反馈推进逻辑复制槽,回收系统表旧版本元组和物理日志。逻辑解码流式加载物理日志抽取逻辑日志,按照CommitLSN有序完成事务解析。考虑事务并发场景下先分配CommitCSN的事务不一定先获取锁写入物理日志,逻辑解码按照日志产生顺序从事务提交日志获取的CommitCSN并不保证有序递增。为了实现按照CommitCSN有序发送事务逻辑日志, 逻辑解码解析到事务提交日志发送前需要识别是否存在CommitCSN比该事务小的事务,优先发送较小CommitCSN事务的逻辑日志。如图所示,逻辑解码在发送逻辑日志进行事务重排逻辑:(1)新增两个双链表toplevel_by_committing_csn和toplevel_by_csn,记录正在提交的事务和已经提交待发送的事务。(2)解码事务句柄新增dependTxnCnt字段记录依赖该事务的数量,新增referTxns单链表记录依赖该事务的事务句柄。(3)解析事务的COMMITTING日志时,将事务按照committingCSN有序添加到toplevel_by_committing_csn链表。(4)解析到事务的COMMIT日志时:将当前事务从toplevel_by_committing_csn移除,所有等待该事务的事务等待计数dependTxnCnt减1;从头往尾遍历toplevel_by_committing_csn,将当前事务添加到CommittingCSN小于当前事务Commit CSN的事务的referTxns链表,并让其dependTxnCnt加1;从尾往头遍历,将当前事务按照CommitCSN有序添加到toplevel_by_csn链表;从头往尾遍历toplevel_by_csn,若事务dependTxnCnt为0,则从链表移除并发送其逻辑日志;直到遇到事务dependTxnCnt不为0或到达链表末尾。3.6 分布式解码事务提交顺序(CommitCSN)代表事务完成的先后顺序。对于有依赖两个事务,后执行事务的CommitCSN大于先执行事务的CommitCSN。若逻辑回放按照CommitCSN从小到大执行,实现业务视角的数据强一致性。分布式逻辑解码按照CommitCSN有序返回事务的逻辑日志,提供逻辑复制数据强一致的基础。如图所示,多DN各自按照事务提交顺序(CommitCSN)返回局部事务的逻辑日志,CN通过堆排序协调汇总来自多DN的事务逻辑日志,CN和DN配合提供全局分布式事务提交顺序(CommitCSN)有序的事务逻辑日志。CN逻辑解码可简单归纳为:从每个DN读取下一个待发送事务的CommitCSN(DN逻辑解码保证下一个事务是该DN CommitCSN最小的事务),通过堆排序查找所有DN中最小CommitCSN的事务,返回该事务的所有逻辑日志给业务。分布式事务涉及多DN的数据变化,每个DN相关事务拥有不同的事务号,但涉及DN所有事务拥有相同的分布式事务提交顺序(CommitCSN)序号。分布式事务对业务来说是一个完整的事务,分布式逻辑解码不能因分布式事务涉及数据分布在多个DN而拆分多个事务,而应该合并多DN的事务逻辑日志作为一个完整的事务。分布式事务的多DN事务逻辑日志合并需要考虑:(1) 多DN之间逻辑日志间的先后关系;(2)逻辑日志先后无关时DN间解码快慢差异。通过堆排序键<CommitCSN, CID, BATCH_ID>阐述相关问题和方案策略。CommitCSN:作为堆排序第一个键,实现按照CommitCSN的顺序返回事务的逻辑日志。CN发送时每次获取小顶堆的堆顶事务,返回来自DN该事务的所有逻辑日志,再根据该DN下一个事务的CommitCSN重新调整堆为小顶堆。CID:Command ID。DDL将单个DN的事务逻辑日志拆分成多个区段,每个区段表的元数据有差异,合并分布式事务在多个DN的逻辑日志需要按照DDL划分的区段进行合并。另外,虽然当前主键必须包含分布键且不允许更新分布键,DN节点内解码保证了主键唯一性的事务前后依赖(按照LSN返回事务的逻辑日志),但是分布式事务在多DN之间的DML操作也可能存在依赖关系。例如:业务操作全局唯一索引先在DN-1删除后在DN-2插入,如果CN逻辑解码合并事务成先在DN-2插入后在DN-1删除,逻辑日志回放出现违反唯一性约束错误。针对DDL和DML混合事务场景,CN汇总DN逻辑日志引入事务CID,实现事务间按照CommitCSN排序、事务内按照CID排序。BATCH_ID:分布式事务同一个SQL可能在不同DN产生众多逻辑日志,考虑DN解码性能和网络状况差异,CN若是在没有收到某DN所需所有逻辑日志之前能够返回其他DN节点该事务CID的就绪逻辑日志,可以减少CN不必要的等待,提升CN逻辑日志汇总性能。引入分布式事务的日志批次编号BATCH_ID,当CN返回DN就绪的某事务某CID的逻辑日志后,仍没有遇到DN该事务下一个CID或下一个事务,则更新该DN发送批次BATCH_ID。同事务同CID其他DN将被调整到堆顶,实现优先发送其他DN已就绪的逻辑日志。逻辑解码在较长时间没有和客户端通信时主动给客户端侧发送keepalive消息,要求客户端侧回复该消息;若是客户端没有回复keepalive消息,逻辑解码主动断开和客户侧的连接,避免客户端hang住长时间占有逻辑复制槽,导致业务无法及时切换启动新的逻辑解码任务。分布式逻辑解码采用多线程异步接收+多DN事务逻辑日志队列,CN及时响应DN发送的keepalive消息,同时减少获取DN事务逻辑日志的同步等待。当DN逻辑解码异常退出,CN将屏蔽集群内部异常,自动连接DN启动解码和异常恢复。以上内容从逻辑复制方面对GaussDB的高可用能力进行了解读,下篇将从两地三中心跨Region容灾方面继续介绍GaussDB高可用相关技术,敬请期待!
  • [问题求助] 检查系统参数的时候提示IO调度有问题,但是我搜索了网上的修改方法,都没法修改
    调度文件无法修改,没法保存
  • [问题求助] GaussDB正式安装的时候提示/lib64/libcrypto.so.10: version `libcrypto.so.10' not found,软链接已经建过了
    救救我,救救我。很奇怪,开始提示是/user/lib64也不存在,建完了之后提示/lib64 
  • [问题求助] 我安装的是centos的,怎么报错是openGauss-6.0.0-RC1-openEuler-64bit.tar.bz2 does not exist不存在
    大神们帮忙看看,很奇怪。
  • [技术解读] 【GaussDB关键技术原理|高可用】DCF&双集群容灾
    GaussDB关键技术原理:高性能篇,从GaussDB数据库性能优化系统概述、查询处理综述、高性能关键技术等方面为大家进行了解读,并对高斯数据库性能优化做了总结。本篇将分享GaussDB高可用方面的相关知识,详细介绍GaussDB的DCF与双集群容灾技术。1 DCF    DCF是Distributed Consensus Framework的简称,它是自研分布式一致性共识框架,基于Paxos协议开发,实现多数派节点自选主自仲裁、日志复制、一致性控制等高可用功能。 1.1 DCF(Distributed Consensus Framework)分布式一致性共识框架    DCF部署于gaussdb进程,以动态库形式提供给DN调用,实现DN节点间自选主自仲裁、XLOG日志复制、回放控制等。DCF主要设计特点如下:  独立API数据复制与内核逻辑隔离;  基于Paxos一致性协议实现日志多副本复制,实现跨AZ极致高可用;  支持多种节点角色:leader、follower、candidate、passive、logger;  支持多日志流通道,支持DN粒度和分区粒度日志分组复制能力;  DCF内部实现通过多处的pipeline、batching、compress等手段提升整体性能。    1.2 DCF功能架构    DCF通过上层API提供给DB kernel调用,在DCF内部主要功能模块如下:  接口:对外提供写入、查询、注册回调等接口  选举:负责主节点的选举、心跳维持、状态通知  复制:负责日志的复制、提交、达成一致控制  元数据:负责管理集群配置信息  存储:负责日志数据的缓存管理和持久化  通信:提供节点间的数据通信功能,并支持压缩解压和SSL能力  基础库:提供线程、日志、锁、队列、定时器等基础能力  1.3 DCF选举流程及优化    选举流程介绍: 除了配置为不可当主的角色(logger、passive)外,启动时各节点一般默认是备机follower角色。节点启动后如果没有收到主节点的心跳,则达到选举超时时间后节点就会发起选主请求,如果节点收集到超过半数节点的应答则可升主。节点升主后会定期给其他节点发送心跳维持权威,其他节点收到心跳后作为备机工作。  每次选出新主都会产生一个新的任期term,这个term是单调递增的。当后续重新选主,term会跟着变大。  如果主节点故障,无法继续发送心跳,其他节点达到选举超时时间后会发起新一轮选举,集群选出新主,继续对外提供服务。  预选举优化: 为防止网络断连导致节点频繁发起选主请求造成term持续增加,采用了优化方案:在Follower变为Candidate前加入pre-candidate状态,发起term不变的预选举流程,成功后才将term增加发起正式选主流程,避免无效的term增加。  租约优化: Leader与多数派断连主动降备,防止出现事实双主。  在lease时间内不再响应新的选主消息,保证选主可靠性。 1.4 DCF日志复制流程                复制流程介绍: 在集群有主的情况下,上层可以调用DCF写接口将日志写给DCF主节点,DCF主节点将日志复制给各个备机,日志并行在主机和各备机落盘,主机收集自身和各备机日志落盘的位置,从而计算得到达成多数派一致性的日志落盘位置,即一致性点。主机会将一致性点同步给备机,整个过程异步、并行、流水线处理。各个节点都有了实时一致性点,主机可以利用一致性点控制业务提交、脏页刷盘、checkpoint等流程,备机可以利用一致性点控制XLOG日志回放,保证业务一致性、各节点不分叉。  1.5 DCF优先级选主和策略化多数派    优先级选主: (1)根据用户指定的AZ和节点优先级顺序,通过节点间信息交互及日志索取机制实现了确定性优先级选主。      (2)高优先级节点异常时,其他节点秒级感知,保证选主RTO。  (3)策略化多数派。  (4)支持灵活动态的策略化多数派,可通过参数配置。  (5)在发生AZ级或城市级故障时,能够在其他AZ选出新主,不丢失数据。  1.6 DCF性能设计                异步流水线: 日志采用全异步pipeline方式进行发送,不采用一问一答同步方式,且支持报文合并发送,提高系统整体吞吐量;  Leader发送完一批log之后,记录发送位置,下次发送从这个位置持续发送,不用等follower响应回来;  Follower落盘线程写完一批log之后,将最新的落盘点发送给leader,持续反馈最新的落盘点;  Leader通过各节点的最新落盘点,推进一致性点。       数据合并与压缩: 报文收发和工作线程采用异步pipeline;  基于端到端共识流控算法自适应调整batch size、 pipeline并发数,提升系统最大吞吐量;  支持将报文按不同压缩算法进行压缩发送,减少网络带宽。  批量并行落盘: 应用端调用write接口,写入内存buffer就返回,不阻塞应用流程处理;  批量写盘和批量发送,日志到buffer之后,并行的将日志落入本地磁盘和发送到follower节点。     1.7 DCF日志与XLOG日志合一设计    为了减少磁盘空间和IO带宽占用、优化性能,我们进行了DCF日志与XLOG日志合一设计,实现XLOG日志只写一份。  DCF日志头和配置日志放在DCF侧(称为控制日志ctrllog)以方便DCF内部处理,XLOG日志格式和之前保持兼容。ctrllog和XLOG建立内部索引关系,相比XLOG其日志量可以忽略不计。  使用XLOG刷盘点计算多数派一致性点,控制业务提交;XLOG刷盘点也是选主的依据。DCF控制日志刷盘以方便业务处理和故障恢复逻辑,限制DCF控制日志刷盘频率避免对XLOG刷盘影响,保证整体性能。  1.8 DCF异常场景处理,高可靠   Leader故障      如图,三节点集群,红色节点表示主机、蓝色表示备机,各节点旁边数字第一行表示日志index,第二行表示任期term,每一列表示一条日志。  leader节点宕机,导致Leader心跳发送停止,日志复制停止。  Follower检测到心跳超时,转换为candidate,发起新任期选举。  Follower若接收到其他节点发起的选举,则判断任期和日志长度,确定是否投票给它。  candidate若得到超过半数的选票,则成为leader,拥有新的任期term。  新leader开始将自己的日志发送给其他follower。  Follower接收新leader来的日志信息,判断日志是否跟自己连续匹配,连续匹配则接受。若不连续则返回,leader重新发送前段日志;若term不匹配,则将新leader的日志覆盖到原来的位置,并将后面的日志truncate掉。最终所有节点的日志都是一致的。      网络分区  五节点集群,分裂为3+2,如图所示:  集群脑裂,分裂出两个小集群。  2节点小集群存在一个原leader,3节点新集群选举一个新leader,任期增1。  原leader无法达成大多数一致,日志无法提交,一定时间内会降备。  新leader能接受写请求进行写入操作,能够达成一致,进行日志提交。  脑裂消失之后,新leader的日志复制给旧leader,将旧leader未提交日志覆盖,集群正常。  2 双集群容灾   GaussDB 双集群容灾方案,是GaussDB提供的一种新架构和部署方式的容灾技术。在已有的容灾方案中,多采用单集群多副本的模式进行跨AZ部署,无法做到故障隔离,类似于集群管理组件的故障或其他区域性的故障将导致整个集群服务不可用;对于传统的基于网络的日志同步方式,数据库主备节点间地理距离的增大将导致传输时延的大幅度增加,直接影响到生产服务的性能。同时,金融、银行业对数据安全有着较高的要求,需要最大限度地保证数据的安全性以及服务的可用性。因此,GaussDB提供了支持RPO=0的数据库双集群容灾方案,即主集群在出现故障的情况下,备集群还具备继续提供服务的能力,当发生自然或人为灾难时,保护数据并快速进行恢复,对数据丢失零容忍。       数据中心架构  双集群部署方式,即每个数据中心分别部署一套独立的GaussDB数据库集群,其中一个数据库集群作为生产集群,提供读和写服务,另一个集群作为灾备集群。  每个数据中心都分别有一个独立的Region和AZ,用来部署GaussDB数据库集群。全量build同步通过云内跨Region跨VPC的BMS之间的网络承载,增量日志同步通过Dorado之间的主备复制承载。      主集群的Redo日志通过网络同步到备集群的存储设备中,主集群的备节点从存储设备中读取Redo日志并进行回放,备集群的备节点从所在分片的存储设备中读取Redo日志并进行回放。当数据库主节点写入的日志同步到备集群的存储设备之后,主节点的事务才会被提交,从而确保了集群切换RPO=0的性能指标。  数据存储不使用本地盘,而是采用Dorado(全闪存共享存储阵列),即每个GaussDB数据库集群都配置一套独立的Dorado作为存储;两套Dorado之间采用主备同步复制,数据复制的模式支持最大保护模式和最大可用模式。  数据中心内部实例级故障时,RPO=0、RTO<=30秒;跨数据中心集群间容灾时,RPO=0、RTO<=60秒。  在同城双集群容灾的基础上,可以和异地集群组成跨Region容灾,即增加一个异地的灾备中心,用于对同城双中心的数据备份,形成两地三中心的容灾解决方案。  核心优势 金融级高可用:支持RPO=0 、RTO<60s的容灾切换,保障业务的安全性和可靠性。当主集群发生故障时,备集群能够数据无损地快速完成切换,替代主集群继续提供生产服务。  高性能:第一,采用物理日志同步相对于逻辑日志同步性能可提升10倍;第二,通过Dorado存储硬件实现集群间日志的快速同步,利用Dorado固有网络协议(密集波分),降低网络时延一倍以上,同时利用Dorado存储的缓存能力,日志写入即刻持久化,降低了事务提交时延。  高可靠:数据安全实现双保险,一方面数据库内核的多副本保障了故障自动切换和恢复,不中断业务;另一方面,存储内核保障了磁盘亚健康、故障容错、硬件自愈等能力。  架构先进性:通过数据库内部计算与存储分离,将存储管理放到下层共享存储中,从而解决数据同步带来的延时问题,并同时增加了计算能力的横向扩展性。      集群隔离:数据库集群间解耦,故障域隔离从而避免全局性的网络故障;集群间版本隔离,避免Bug污染,能够快速回切;集群间资源隔离,按照Region进行资源管理和调度,方便数据库管理员对数据库系统资源使用进行规范和约束。  双集群容灾方案进一步提升了GaussDB的高可用能力,特别是针对性能和稳定性有更高要求的金融核心业务场景,提供了安全可靠的数据库服务,使数据库无惧灾难,为用户的生产业务保驾护航。  以上内容从DCF与双集群容灾技术两方面对GaussDB的高可用能力进行了解读,下篇将从逻辑复制方面继续介绍GaussDB高可用相关技术,敬请期待! 
  • [问题求助] PostgreSQL 9.2.4 (GaussDB 8.1.3 ) 能否本地安装进行开发调试
    请问PostgreSQL 9.2.4 (GaussDB 8.1.3 build dda5d0f6)能否支持本地下载安装,进行业务开发调试?
  • [问题求助] 时间范围分区表,怎么样创建表,让表根据数据,自动创建对应分区,比如 ,2024-12-01数据进来,就创建当日的分区。
    时间范围分区表,怎么样创建表,让表根据数据,自动创建对应分区,比如 ,2024-12-01数据进来,就创建当日的分区。我的语句 CREATE table t2( gddwm VARCHAR2(20), sjsj date )partition by RANGE("sjsj") INTERVAL('1 day') ( PARTITION "P_20240101" VALUES LESS THAN(TO_DATE('2024-01-02 00:00:00','YYYY-MM-DD HH24:MI:SS')), PARTITION "P_20240102" VALUES LESS THAN(TO_DATE('2024-01-03 00:00:00','YYYY-MM-DD HH24:MI:SS')), PARTITION "P_20240103" VALUES LESS THAN(TO_DATE('2024-01-04 00:00:00','YYYY-MM-DD HH24:MI:SS')) ); 主备版本报错,ERROR:Interval partitioned table is only supported in single-node mode. 有什么替代方法?
  • [技术干货] openGauss存储过程创建及应用
    一、引言openGauss 是一款开源关系型数据库管理系统,广泛应用于企业级应用中。随着数据量的增长和业务逻辑的复杂化,数据库管理和操作的自动化需求越来越高。存储过程(Stored Procedures)作为数据库中重要的编程工具,能够极大地简化复杂操作,提高系统的性能和安全性。本文将详细介绍 openGauss 的存储过程,并提供具体的代码和案例,以帮助读者更好地理解和应用这些工具。二、存储过程1. 什么是存储过程存储过程是一组预先编写好的 SQL 语句集合,存储在数据库中,可以通过调用存储过程来执行一系列操作。存储过程能够简化复杂的数据库操作,减少代码重复,提高效率。此外,存储过程运行在数据库服务器端,这意味着可以减少客户端和服务器之间的通信开销,提高执行效率。存储过程的特点包括:封装性:将一系列操作封装在一个过程里,简化调用。重用性:定义一次,可以在多个地方调用,减少代码重复。安全性:通过存储过程可以控制访问权限,提高数据安全性。性能:减少客户端和服务器之间的通信,执行效率高。2. 创建和使用存储过程在 openGauss 中,创建存储过程使用 CREATE PROCEDURE 语句。一个存储过程可以包含多个输入参数、输出参数,甚至没有参数。下面是一个详细的例子,演示如何创建和调用存储过程。创建员工表-- 创建员工表CREATE TABLE employees (id INT PRIMARY KEY,name VARCHAR(100),salary NUMERIC(15, 2),department VARCHAR(100));创建存储过程-- 创建插入员工的存储过程CREATE OR REPLACE PROCEDURE add_employee(emp_id INT,emp_name VARCHAR,emp_salary NUMERIC,emp_department VARCHAR)LANGUAGE plpgsql AS $$BEGININSERT INTO employees (id, name, salary, department)VALUES (emp_id, emp_name, emp_salary, emp_department);END;$$;-- 创建更新触发器函数-- 创建更新员工的存储过程CREATE OR REPLACE PROCEDURE update_employee(emp_id INT,emp_name VARCHAR,emp_salary NUMERIC,emp_department VARCHAR)LANGUAGE plpgsqlAS $$BEGINUPDATE employeesSET name = emp_name, salary = emp_salary, department = emp_departmentWHERE id = emp_id;END;$$;-- 创建删除员工的存储过程CREATE OR REPLACE PROCEDURE delete_employee(emp_id INT)LANGUAGE plpgsqlAS $$BEGINDELETE FROM employeesWHERE id = emp_id;END;$$;-- 创建查询员工的存储过程CREATE OR REPLACE PROCEDURE get_employee(emp_id INT)LANGUAGE plpgsqlAS $$BEGINPERFORM * FROM employees WHERE id = emp_id;END;$$;调用存储过程-- 调用存储过程插入员工CALL add_employee(1, 'John Doe', 50000, 'Engineering');-- 调用存储过程更新员工CALL update_employee(1, 'John Doe', 55000, 'Marketing');-- 调用存储过程删除员工CALL delete_employee(1);-- 调用存储过程查询员工CALL get_employee(1);3. 存储过程的高级应用存储过程不仅可以简化常见的增删改查操作,还可以用于更复杂的业务逻辑处理。以下是一些存储过程的高级应用场景:批量数据处理在实际业务中,经常需要对大量数据进行批量处理,如批量插入、批量更新等。使用存储过程可以极大地简化这些操作,并提高执行效率。-- 定义员工记录的复合类型CREATE TYPE emp_record AS (id INT,name VARCHAR(100),salary NUMERIC(15, 2),department VARCHAR(100));-- 创建批量插入员工的存储过程CREATE OR REPLACE PROCEDURE batch_insert_employees(emp_records emp_record[])LANGUAGE plpgsqlAS $$DECLARErec emp_record;BEGINFOREACH rec IN ARRAY emp_recordsLOOPINSERT INTO employees (id, name, salary, department)VALUES (rec.id, rec.name, rec.salary, rec.department);END LOOP;END;$$;-- 调用批量插入存储过程CALL batch_insert_employees(ARRAY[ROW(2, 'Jane Doe', 60000, 'HR')::emp_record,ROW(3, 'Alice', 70000, 'Finance')::emp_record,ROW(4, 'Bob', 80000, 'IT')::emp_record]);数据校验和清洗在存储过程中可以添加数据校验和清洗的逻辑,确保插入数据库的数据的完整性和准确性。例如,可以在插入员工数据前,检查数据是否符合业务规则。CREATE OR REPLACE PROCEDURE add_employee_with_validation(emp_id INT,emp_name VARCHAR,emp_salary NUMERIC,emp_department VARCHAR)LANGUAGE plpgsqlAS $$BEGINIF emp_salary < 0 THENRAISE EXCEPTION 'Salary cannot be negative';END IF;IF emp_department IS NULL THENRAISE EXCEPTION 'Department cannot be null';END IF;INSERT INTO employees (id, name, salary, department)VALUES (emp_id, emp_name, emp_salary, emp_department);END;$$;-- 调用存储过程插入员工CALL add_employee_with_validation(5, 'Charlie', 5000, 'Sales');自动化任务存储过程可以用于自动化任务,如定时任务、数据备份等。可以结合数据库调度器(如 cron 表达式)来实现定时调用存储过程,完成自动化管理。-- 定时任务:每天凌晨2点备份员工表CREATE OR REPLACE PROCEDURE backup_employees()LANGUAGE plpgsqlAS $$BEGINEXECUTE 'COPY employees TO ''/path/to/backup/employees_' || to_char(current_date, 'YYYYMMDD') || '.csv'' WITH CSV HEADER';END;$$;
  • [问题求助] 关于JDBC在不同场景下连接配置问题
    官方的容灾场景的架构配置为:A集群生产3节点 , B集群容灾3节点.如果B集群容灾为单节点JDBC在配置连接串时应如何进行配置  , 假设 node4 为容灾单节点为只读官方的介绍为 : jdbc:gaussdb://node1,node2,node3,node4/database?autoBalance=shuffle如果写成 : jdbc:gaussdb://node1,node2,node3,node4/database?autoBalance=true&priorityServers=3  需求为 : 在JDBC有连接池的情况下 ,优先连接主集群3节点 , 在发生主备切换后自动连接容灾单节点 , 等主集群修复后进行二次切换 , 通过 JDBC 连接串自动连接主集群3节点.
  • [技术解读] GaussDB多模数据库的设计思想
     GaussDB多模数据库的设计思想设计思想:在数据库系统之上提供统一的多模数据管理、处理能力,以及统一运维能力。 多模数据的存储:对于一个统一的多模数据库系统而言,需要提供多种数据模型的存储能力,包括关系、时序、流图、空间等。 多模数据的处理:对于一个统一的多模数据库系统而言,需要提供多种数据库模型的处理能力,包括关系、时序、流图、空间等。 多模数据之间的相关转换:大多数情况下,客户的数据产生源只有一个,即数据产生源的数据模型是单一的,但是后续处理可能需要使用多种模型来表征物理世界,进而进行数据处理,或者需要通过多种模型之间的相互协作来完成单一任务。因此,不同模型之间的数据转换也是极为重要的。 多模数据库系统架构 引入多模数据库统一框架(Multi–Model Database Uniform Framework),为用户提供关 系数据库、图数据库、时序数据库等多模数据库统一数据访问和维护接口,简化运维和应用开发人 员的学习和使用成本,提升了数据使用安全性(数据无须在多个系统之间进行倒换,减少了数据在 网络上暴露的时间)。 
  • [技术解读] GaussDB数据库语法及gsql入门
     一、GaussDB数据库语法入门 之前我们讲了如何连接数据库实例,那连接数据库后如何使用数据库呢?那么我们今天就带大家了解一下GaussDB,以下简称GaussDB的基本语法。  关于如何连接数据库,请戳这里。  学习本节课程之后,您将可以完成创建数据库、创建表及向表中插入数据和查询表中数据等操作。  1、前提条件 •   GaussDB实例正常运行。  •   已通过DAS或gsql连接数据库实例。  2、操作步骤 通过DAS或gsql连接数据库实例。 创建数据库用户。       默认只有创建实例时的管理员用户可以访问初始数据库,您还可以手动创建其他数据库用户帐号。  postgres=# CREATE USER joe WITH PASSWORD "xxxxxxxx";       xxxxxxxx需要替换为指定的密码,当结果显示为如下信息,则表示创建成功。  CREATE ROLE       如上创建了一个用户名为joe,密码为xxxxxxxxx的用户。        如下命令为设置joe用户为系统管理员。  postgres=# GRANT ALL PRIVILEGES TO joe;       使用GRANT命令进行相关权限设置,具体操作请参考GRANT。        引申信息:GaussDB对于用户可以进行灵活的权限控制,想要了解请戳管理用户及权限。  创建数据库。 postgres=#  CREATE DATABASE db_tpcds;       当结果显示为如下信息,则表示创建成功。  CREATE DATABASE       创建完db_tpcds数据库后,就可以按如下方法退出postgres数据库,使用新用户连接到此数据库执行接下来的创建表等操作。当然,也可以选择继续在默认的postgres数据库下做后续的体验。  postgres=#  \q   gsql -d db_tpcds -p 8000 -U joe   Password for user joe:   gsql  compiled at 2020-05-08 02:59:43 commit 2143 last mr 131)   Non-SSL connection (SSL connection is recommended when requiring high-security)   Type "help" for help.       db_tpcds=>  创建表。     创建一个名称为mytable,只有一列的表。字段名为firstcol,字段类型为integer。  db_tpcds=>  CREATE TABLE mytable (firstcol int);        未使用“DISTRIBUTE BY”指定分布列时,系统默认会指定第一列为哈希分布列,且给出提示。系统返回信息以“CREATE TABLE”结束,表示创建表成功。  NOTICE:  The 'DISTRIBUTE BY' clause is not specified. Using 'firstcol' as the distribution column by default.  HINT:  Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column.  CREATE TABLE    向表中插入数据:  db_tpcds=> INSERT INTO mytable values (100);        当结果显示为如下信息,则表示插入数据成功。  INSERT 0 1    查看表中数据:  db_tpcds=> SELECT * from mytable;   firstcol   ----------        100  (1 row)       引申信息:  默认情况下,新的数据库对象是创建在“$user”模式下的,例如刚刚新建的表。关于模式的更多信息请参考创建和管理schema。 关于创建表的更多信息请参见创建和管理表。 除了创建的表以外,数据库还包含很多系统表。这些系统表包含集群安装信息以及GaussDB上运行的各种查询和进程的信息。可以通过查询系统表来收集有关数据库的信息。请参见查看系统表。  二、GaussDB数据库gsql入门 gsql是GaussDB提供在命令行下运行的数据库连接工具,可以通过此工具连接服务器并对其进行操作和维护,除了具备操作数据库的基本功能,gsql还提供了若干高级特性,便于用户使用。  1、基本功能 连接数据库:可以通过gsql远程连接数据库实例。如何使用gsql连接数据库请参考连接实例。 执行SQL语句:支持交互式地键入并执行SQL语句,也可以执行一个文件中指定的SQL语句。 执行元命令:元命令可以帮助管理员查看数据库对象的信息、查询缓存区信息、格式化SQL输出结果,以及连接到新的数据库等。 2、使用指导 步骤 1 使用gsql连接到GaussDB实例。  gsql工具使用-d参数指定目标数据库名、-U参数指定数据库用户名、-h参数指定主机名、-p参数指定端口号信息。  若未指定数据库名称,则使用初始化时默认生成的数据库名称;若未指定数据库用户名,则默认使用当前操作系统用户作为数据库用户名;当某个值没有前面的参数(-d、-U等)时,若连接的命令中没有指定数据库名(-d)则该参数会被解释成数据库名;如果已经指定数据库名(-d)而没有指定数据库用户名(-U)时,该参数则会被解释成数据库用户名。  示例,使用jack用户连接到远程主机postgres数据库的8000端口。  gsql -h 10.180.123.163 -d postgres -U jack -p 8000 详细的gsql参数请参见命令参考。  步骤 2 执行SQL语句。  以创建数据库human_staff为例。  CREATE DATABASE human_staff; CREATE DATABASE 通常,输入的命令行在遇到分号的时候结束。如果输入的命令行没有错误,结果就会输出到屏幕上。  步骤 3 执行gsql元命令。  以列出GaussDB中所有的数据库和描述信息为例。  postgres=#  \l                                 List of databases       Name      |  Owner   | Encoding  | Collate | Ctype |   Access privileges    ----------------+----------+-----------+---------+-------+-----------------------  human_resource | root | SQL_ASCII | C       | C     |   postgres       | root | SQL_ASCII | C       | C     |   template0      | root | SQL_ASCII | C       | C     | =c/root         +                 |          |           |         |       | root=CTc/root  template1      | root | SQL_ASCII | C       | C     | =c/root          +                 |          |           |         |       | root=CTc/root  human_staff    | root | SQL_ASCII | C       | C     |  (5 rows) 更多gsql元命令请参见元命令参考。  3、示例 以把一个查询分成多行输入为例。注意提示符的变化:  postgres=# CREATE TABLE HR.areaS( postgres(# area_ID   NUMBER, postgres(# area_NAME VARCHAR2(25) postgres-# )tablespace EXAMPLE; CREATE TABLE 查看表的定义:  postgres=# \d HR.areaS                Table "hr.areas"   Column   |         Type          | Modifiers  -----------+-----------------------+-----------  area_id   | numeric               | not null  area_name | character varying(25) | 向HR.areaS表插入四行数据:  postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (1, 'Europe'); INSERT 0 1 postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (2, 'Americas'); INSERT 0 1 postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (3, 'Asia'); INSERT 0 1 postgres=# INSERT INTO HR.areaS (area_ID, area_NAME) VALUES (4, 'Middle East and Africa'); INSERT 0 1 切换提示符:  postgres=# \set PROMPT1 '%n@%m %~%R%#' root@[local] postgres=# 查看表:  root@[local] postgres=#SELECT * FROM HR.areaS;  area_id |       area_name         ---------+------------------------        1 | Europe        4 | Middle East and Africa        2 | Americas        3 | Asia (4 rows) 可以用\pset命令以不同的方法显示表:  root@[local] postgres=#\pset border 2 Border style is 2. root@[local] postgres=#SELECT * FROM HR.areaS; +---------+------------------------+ | area_id |       area_name        | +---------+------------------------+ |       1 | Europe                 | |       2 | Americas               | |       3 | Asia                   | |       4 | Middle East and Africa | +---------+------------------------+ (4 rows)   root@[local] postgres=#\pset border 0 Border style is 0. root@[local] postgres=#SELECT * FROM HR.areaS; area_id       area_name         ------- ----------------------       1 Europe       2 Americas       3 Asia       4 Middle East and Africa (4 rows)  使用元命令:  root@[local] postgres=#\a \t \x Output format is unaligned. Showing only tuples. Expanded display is on.   root@[local] postgres=#SELECT * FROM HR.areaS; area_id|2 area_name|Americas   area_id|1 area_name|Europe   area_id|4 area_name|Middle East and Africa   area_id|3 area_name|Asia  三、总结 云数据库 GaussDB各特性版本的功能发布和对应的文档动态,欢迎体验。  GaussDB是华为公司倾力打造的自研企业级分布式关系型数据库,该产品支持优异的分布式事务,同城跨AZ部署,数据0丢失,支持1000+扩展能力,PB级海量存储等企业级数据库特性。拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。  
  • [技术解读] GaussDB关键技术原理:高性能(五)
    GaussDB 关键技术原理:高性能(四)从 USTORE 存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP 并行执行等五方面对高性能关键技术进行解读,本篇将从 LLVM 动态查询编译执行、SQL-BYPASS 执行优化、线程池化、多核处理器优化、日志无锁刷新与多级流水等方面继续介绍 GaussDB 高性能关键技术,并对高斯数据库性能优化进行总结。3.11 LLVM 动态查询编译执行在传统经典执行器算子中基于遍历树的表达式计算框架,这种框架的好处是清晰明了,但是在性能上却不是最优的,主要有以下几个原因:(1)表达式计算其框架的通用性决定了其执行模式要适配各种不同的操作符和数据类型,因此在运行时要根据其表达式遍历的具体结果来确定其执行的函数和类型,对这些类型的判断要引入非常多的分支判断。(2)表达式计算在整体的执行过程中要进行多次的函数调用,其调用的深度取决于其树的深度,这一部分也有着非常大的开销。这两个核心原因,分支判断和函数调用同样在执行算子中也是影响性能的关键因素,为了提升其执行速度,GaussDB 引入了业界著名的开源编译框架 LLVM(Low Level Virtual Machine)来提速的执行速度,LLVM 是一个通用的编译框架,能够支持不同的计算平台。LLVM 提升整体表达式计算的核心要点如下:(1)GaussDB 内置的 LLVM 编译框架通过为每一个计算单元(表达式或者执行算子里面的热点函数)生成一段独特的执行代码,由于在编译的时候提前知道了表达式涉及的操作和数据类型,为这个表达式生成的执行代码将所有的逻辑内联,完全去除函数调用。GaussDB 内置的 LLVM 编译为这个表达式生成了一段特殊代码。里面已经没有任何其他的函数调用,所有的函数都已经被内联在一起,同时去掉了关于数据类型的分支判断。(2)LLVM 编译框架利用编译技术最大程度的让生成的代码将中间结果的数据存储在 CPU 寄存器里,让数据读取的速度加快。LLVM 通过消除条件逻辑冗余,降低虚函数调用次数,改善数据 locality,可大大降低任务执行代价;LLVM 生成的 machine code 为一次性成本,整个执行过程均可使用,数据量越大,所获取的收益将越大,因此对于一个可以实施 LLVM 动态编译优化的查询,其收益随着数据量的增多会逐步增加,对应的性能提升比例也会越来越大3.12 SQL-BYPASS 执行优化在典型的 OLTP 场景中,简单查询占了很大一部分比例。这类查询本身大多数会走索引、分区剪支、只涉及单表和简单表达式的查询,这类查询的有效数据读取占比在这个查询解析、执行过程中并不大,即便使用计划缓存技术(PBE)把查询解析部分省下来以后,执行器初始化 exec_init_*() 仍然会有比较明显的开销,例如下面火焰图所 profiling 的场景,执行器初始化开销占比超过 40%,并且每个同样的模板查询这部分的操作都是无效的重复开销,有效部分只有 Operator::get_next (),占比只有 15% 左右。因此为了加速这类查询,提出了 SQL-BY-PASS 框架,其核心思想是对执行路径 inline 处理优化,减少不必要的执行器函数迭代的开销,在 parse 层对这类查询做简单的模式判别后,进入到特殊的执行路径里,跳过经典的执行器执行框架,包括算子的初始化与执行、表达式与投影等经典框架,直接重写一套简洁的执行路径,并且直接调用存储接口,这样可以大大加快简单查询的执行速度。以分区表点差举例,通过 SqlByPass 技术将分区表的执行过程进行扁平化 inline 处理,将原来 SQL 执行引擎中很深的调用栈扁平化,性能提升 30%。3.13 线程池化在 OLTP 领域中数据库通常需要处理大量的客户端连接。因此,高并发场景的处理能力是数据库的重要能力之一。对于外部连接最简单的处理模式是 per-thread-per-connection 模式,即来一个用户连接产生一个线程。这个模式好处是架构上处理简单,但是高并发下,由于线程太多,线程切换和数据库轻量级锁区域的冲突过大导致性能急剧下降,使得系统性能(吞吐量)严重下降,无法满足用户性能的 SLA。归纳起来每当面对高并发业务(线程 / CPU 核数比大于 10)场景时,系统通常面临以下几个方面挑战:(1)资源耗尽,由于接入的会话数过多导致消耗过多的内存、连接数资源耗尽产生系统宕机、OOM 等异常,造成系统可用性降低。(2)过度争抢,由于并发数过多而具体 CPU 计算有限,增加了临界区锁、信号量等处理开销,大量资源并未产生客户实际吞吐量。(3)相互影响,如果某一个会话请求占用过多的 CPU、内存资源导致对其他会话资源的挤占,造成单个请求拖垮整个系统的严重问题。因此,对于高并发性能稳定性从本质上分析,数据库系统需要从设计上解耦接入会话数与资源使用量 & 争抢之间的线性耦合关系,同时对极端 “炸弹式” 请求需要有有效的管控措施,将其影响控制在有限的范围内。GaussDB 主要的解决方案过线程资源池化复用的技术来解决该问题。线程池技术的整体设计思想是线程资源池化,并且在不同连接之间复用。系统在启动之后会根据当前核数或者用户配置,启动固定一批数量的工作线程,一个工作线程会服务一到多个连接 session,这样把 session 和 thread 进行了解耦。因为工作线程数是固定的,因此在高并发下不会导致线程的频繁切换,而由数据库层来进行 session 的调度管理。高斯数据库线程池实现主要体现在以下 3 个方面:(1)资源解耦:将接入会话 & 工作线程进行解耦隔离,确保高并发场景下系统资源不会持续增加而是保持稳定。(2)多核优化:在多核场景下考虑到 NUMA 效应,线程池针对工作线程的调度范围根据 NUMA node 进行分配和限制,避免线程的调度跨 numa,降低处理时延提升性能。(3)资源管控:线程池化基础上实现以工作线程为粒度的过载管控,避免单一线程占用过多资源,提升系统可靠性。通过线程池化改进后相比高并发场景下具有明显的性能稳定性,以下是数据库性能稳定性测试,通过标准 OLTP 负载模型(TPCC)的测试结果。并发数MySQL 非线程池GaussDB(线程池)100339,171.29852,701.91200401,879.301,267,780.87400380,815.541,616,192.10600344,775.511,693,294.49800316,093.141,663,179.511600250,559.431,632,902.632400207,585.541,631,816.553200181,735.221,615,253.23总结:在线程池的帮助下数据库系统面对大并发场稳定性、性能两个方面都有明显提升。(1)稳定性:随着并发数增加 MySQL 无线程模式的数据库性能在 CPU 资源满了以后并不会像 GaussDB 这样保持稳定。(2)高性能:数据库线程池化考虑多核 CPU NUMA 亲和以后进一步提升性能,相比 MySQL 有明显优势。3.14 多核处理器优化鲲鹏 ARM 服务器多 CPU-socket 架构下跨 NUMA 内存访问延迟存在严重的不对称,远 / 近端内存访存时延有成倍数差异,同时相比 x86 内存访问时延高 50%、并发控制原语代价高 2-3 倍,在数据库中会以进一步恶化 OLTP 瓶颈,尽管通常在架构下 CPU 物理核心数相比 x86 有了一定提升,但如果不合理设计和实现数据库内核关键数据结构、线程调度模型无法充分利用 ARM 多核的优势,如何优化 NUMA 带来的访问时延问题,如何充分利用众核 CPU 解决并发控制问题成为了鲲鹏上优化数据库 OLTP 负载性能的主要挑战。使用标准事务型负载 TPMC benchmark 测试结果 96 核 x86 135w,128 核 ARM 在 NUMA 优化前只有 110w tpmC 左右。GaussDB Kernel 根据 ARM 处理器的多核 NUMA 架构特点,进行针对性一系列 NUMA 架构相关优化,主要围绕三个方面进行:(1)线程调度访存本地化:减少跨核内存访问的时延问题,让线程调度尽可能在单个 NUMA 节点内,同时针对高频热点数据结构通过适当的冗余保留在本地,减少跨 NUMA 远端内存访问。(2)ARM 多核算力优化:针对鲲鹏 ARM 体系下计算核心多的优势,对数据库查询处理、数据库缓冲区脏页处理、WAL 日志等关键处理流程进行 multi-thread 多级流水线改造,将原有单线程处理流程下发给多个 CPU - 线程进行并行处理提升总体性能。(3)ARM 指令集优化:借助 ARMv8.1 引入的新的原子操作 LSE,将大量的可转换为原子类型操作(plus、minus、CAS)的部分,替换为 ARM 硬件相关原语 LSE 指令集,从而提升多线程间同步性能,例如工作线程 - WAL 写入性能等。3.15 日志无锁刷新与多级流水在写事务型负载中日志落盘位于性能关键路径,为了确保数据可靠性在执行 INSERT、DELETE、UPDATE 等操作均需要记录。经过在多核环境上的性能测试,我们发现日志在 Flush 时存在大量的等待,其本质原因是当前在并发场景下日志落盘环节中很难在 WalInsertLock 数量和锁遍历开销中取得平衡最优解,导致成为瓶颈。上图展示了常见的日志的实现方案,主要可以归纳成 3 个方面:(1)数据库内核线程必须获取日志插入锁 WALInsertLock 才能进入第一个临界区,在临界区中,Backend 线程首先会预留 WAL 的插入位置,然后将生成的 WAL 复制到 WAL Buffer 的对应预留位置中。由于是多个数据库后台线程进行的并发拷贝,每个 Backend 线程拷贝完成的时机并不一致。(2)数据库后台线程需要遍历所有的 WALInsertLock 检查 lsn 是否已经下盘,当 WALInsertLock 的数目越多时,在执行 WAL Flush 之前等待其他 Backend 线程将日志拷贝完成的时间就越长。(3)WALInsertLock 的数目越少时,XLog 插入锁的抢占就越激烈。所以不管 WALInsertLock 的数量如何变化,系统的性能都很难达到最优,这成为了目前日志落盘的瓶颈。GaussDB 针对 WalInsertLock 日志锁进行优化,利用 LSN(Log Sequence Number)及 LRC(LogRecord 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 去分发,更好的提高并行回放的并行程度。Ustore 存储引擎…4 高斯数据库性能优化总结高斯数据库 GaussDB 华为公司过去 10 年打造的一款高性能 OLTP 交易型数据库产品,在迭代演进过程当中吸纳当今主流数据的技术与思路,确保架构和演进层面的领先性,在达到高性能的同时能够保证事务的强一致性,在国内泛金融领域、保险、等主要行业、公司内部 ERP 等有广泛的应用和成功落地实践。首先,高斯数据库从架构层面需要保证处理能力可持续提升、可横向扩展,避免某一单点问题阻碍上限的提升,因此最初架构演进上就做过深入的考虑,因此在相同代码基础上同时具备分布式、集中式两种不同的部署形态,这里集中式部署形态决定了单节点(单分片)的性能上限,而分布式将多个数据分片结合到一起通过横向扩展提升总体上限。因此从产品架构维度上看,高斯数据库的高性能技术点可分成集中式、分布式两个优化维度。(1)集中式性能维度,主要聚焦数据库进程内的算法实现,其目标在于将节点内有限计算资源有效最大化利用。首先,从查询执行算法的宏观维度,优化器通过查询重写、CBO/ABO 代价模型确保查询整体执行步骤最优;其次,执行引擎将执行计划内的每个算子执行效率发挥出来,通过节点内 SMP 对称多线程并行处理技术将多核 CPU 资源加以利用实现处理任务时序在时间维度重叠达到提升,通过算子 Vec 向量化、CodeGen/LLVM 化等技术实现局部编译器执行,确保了 CPU 指令集微观层的优化效果,此外集中式场景还考虑单节点大容量数据场景,执行层面提供了丰富可选数据分区策略(Range、List、Hash、Interval、二级组合分区)能够根据用户业务的定义对数据查询范围进行数量级的裁剪,通过 ustore 存储引擎确保读写混合负载长稳性能以及空间节省,同时为了保证数据的强一致性处理 WAL 日志落盘也进行了异步流水化改造提升单位时间内日志持久化落盘的速率,进而提升读写事务的性能。再次,在性能稳定性层面,同样做了线程池化、内存共享化改造能够确保并发线程在内存、CPU 调度之间得到平衡,能够在极致并发场景下如 5x(相对满负荷负载并发)并发性能不显著下降,十倍甚至百倍并发系统不崩溃,并已在公司 MetaERP 项目中得到过实战检验。(2)分布式性能维度,主要聚焦多数据分片汇聚线性度确保性能可横向扩展,在高斯数据库里实现了 CN 轻量化技术、分布式单分片事务降低 CN 路由和本地事务处理开销能够在 256 大集群内线性度达 0.85 以上,对于分布式事务提供了轻量化全局事务 GTM-lite 技术能够让分布式事务开销进一步降低,在标准 TP 点查负载模型下 32 节点以内线性度达到 0.9 以上。分布式大数据量处理处理场景下,分布式优化器能够基于全据统计信息合理生成分布式查询计划确保在数据搬迁 - 本地计算量两个维度获得最优解,实现跑批处理的高效性,分布式执行框架串联多个分片计算单元在分片间实现并行计算,实现节点内 - 节点间的双重并行叠加最大化分布式系统的资源利用率,在数据分布层面同样提供 HASH、LIST、RANGE 分布策略供客户应用场景进行选择,实现了分布 - 集中式分区两个维度的数据分片能力叠加,极大提升了大数据量场景下的数据剪枝优化能力,并在 CBG、邮储等核心业务系统中得到实战检验其次,为了确保高斯数据库性能易用性,针对历史版本升级、异常场景下的逃生策略同样做了一些列性能辅助特性,例如 SPM 计划管理、SQL-PATCH 能够在版本升级、系统迁移、统计信息突变场景下对已有 optimal 计划起到保护作用,避免计划跳变导致的性能劣化,基于线程调度抗过载逃生能有效控制慢查询等 “性能炸弹” 进行有效隔离,在企业应用的一些边界极端场景确保数据库性能 SLA 达成。回顾过去,GaussDB 在演进迭代过程中积极吸取了时下关系型数据库、分布式数据库的设计与优化方案,在短短的 10 年内走完了 A 国友商 40 年的演进历程,同时并未对分布式 TP/AP 系统的复杂性妥协,在确保单节点性能领先的前提下仍然可通过分布式提升整体的性能上限并具备 0.85 + 不错线性扩展比。放眼未来,随着计算机软硬件、OS / 编译器 / 网络协议等基础软件不断革新,高斯数据库性能优化也扎根到与之相结合的新高度,在近年出现的多核 128/256 多核 CPU,鲲鹏 /x86 体系结构相关背景下基于多核 NUMA 的优化方案也在产品里落地商用,其中鲲鹏 2/4 路 180w/230w tpmC、32 节点 1600w tpmC 的优势更是在友商性能性能比拼测试中获胜,此外还进行编译器相结合的优化,基于毕昇编译器的 PGO、LTO、BOLT、静态编译优化等手段已在局点实战比拼中提升已有上限的 20-30%,进一步巩固领先优势并在可预见的将来落地商用版本。欢迎小伙伴们交流~
  • [技术解读] GaussDB关键技术原理:高性能(四)
    GaussDB关键技术原理:高性能(三)从查询重写RBO、物理优化CBO、分布式优化器、布式执行框架、轻量全局事务管理GTM-lite等五方面对高性能关键技术进行了解读,本篇将从USTORE存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP并行执行等方面继续介绍GaussDB高性能关键技术。3.6 USTORE存储引擎GaussDB新增的Ustore存储引擎,相比于Append Update(追加更新)行存储引擎,Ustore存储引擎可以提高数据页面内更新的HOT UPDATE的垃圾回收效率,有效减少多次更新元组后存储空间占用的问题。设计原理上Ustore存储引擎采用NUMA-aware的Undo子系统设计,使得Undo子系统可以在多核平台上有效扩展;同时采用多版本索引技术,解决索引清理问题,有效提升了存储空间的回收复用效率。Ustore存储引擎结合Undo空间,可以实现更高效、更全面的闪回查询和回收站机制,能快速回退人为“误操”为GaussDB Kernel提供了更丰富的企业级功能。Ustore基于Undo回滚段技术、页面并行回放技术、多版本索引技术、xLog无锁落盘技术等实现了高可用高可靠的行存储引擎。USTORE存储引擎作为原有ASTORE存储引擎的替代者其核心目标定位于:(1)针对OLTP场景,实现Inplace-update,利用Undo实现新旧版本分离存储;降低类似于AStore存储引擎由于频繁更新或闪回功能开启导致的数据页空间膨胀,以及相应的索引空间膨胀。(2)通过在DML操作过程中执行动态页面清理,去除VACUUM依赖,减少由于异步数据清理产生的大量读写I/O。通过Undo子系统,实现事务级的空间管控,旧版本集中回收。(3)对插入、更新、删除等各种负载的业务,性能和资源使用表现相对平衡。在频繁更新类的业务场景中,更新操作采用原地更新模式,可以获得更高、更平滑的性能表现。适合“短”(事务短)、“频”(更新操作频繁)、“快”(性能要求高)的典型 OLTP类业务场景3.7 计划缓存计划技术数据库接收到SQL语句后通常要经过如下处理:词语法解析->优化重写->生成执行计划-> 执行,从开始解析到计划生成其实是一个比较耗时的过程,一个常用的思想就是将计划缓存下来,当执行到相似的SQL时,从而可以复用计划,跳过SQL语句生成执行计划的整个过程,在一般OLTP业务负载中,由于涉及到的数据量较少,同时借助索引技术能够大大加速数据的访问路径,因此查询的解析、重写、优化阶段占比会比价高,如果能够讲一些模板性质的语句计划缓存起来,每次设置不同的参数那么点查询的处理流程能够大大简化,提升查询时延和并发吞吐量。计划缓存技术:当数据库收到一条 SQL 请求后,首先会通过查询即系模块对 SQL 文本做一次快速参数化处理,参数化处理的作用是把 SQL 文本中的常量参数替换成通配符 ?,例如 SELECT * FROM t1 WHERE c1 = 1 会被替换为 SELECT * FROM t1 WHERE c1 = ?。接着数据库会从计划缓存中查看有没有已经生成好的计划给这条参数化后的 SQL 使用。如果找到了可用的计划,数据库就会直接执行这个计划。如果没有找到可用的计划,数据库会重新为这条 SQL 生成执行计划,并把生成好的计划保存到计划缓存中以备后续的 SQL 使用。通常情况下从计划缓存中直接获取执行计划相比于重新生成执行计划,耗时通常会低至少一个数量级,因此使用计划缓存可以大大降低获取执行计划的时间,从而减少 SQL 的响应时间。上图为对比走计划缓存、不走计划缓存的SQL执行过程,可以看到执行待计划缓存的查询语句可以规避掉大量的处理逻辑,在OLTP并发负载场景下提升效果镜像,首先,事务型负载单条查询执行时间本身就在毫秒级ms,查询解析、RBO/CBO优化等一些列过程也是毫秒级往往会超过查询本身的执行时间,另一方面,查询解析、RBO/CBO本身是消耗CPU计算资源的操作,这对事务型高并发、高吞吐的事务型复杂起来说非常明显的资源占用,如果能将这部分资源剩下、同时将查询解析的时延消减为0对整体性能是非常明显的提升3.8 数据分区与分区剪枝在数据系统中,数据分区是在一个实例内部按照用户指定的策略对数据做进一步的数据切分,将表按照指定规则划分为多个数据互不重叠的部分。从数据分区的角度来看是一种水平分区(horizontal partition)分区策略方式。分区表增强了数据库应用程序的性能、可管理性和可用性,并有助于降低存储大量数据的总体拥有成本。分区允许将表、索引和索引组织的表细分为更小的部分,使这些数据库对象能够在更精细的粒度级别上进行管理和访问。GaussDB Kernel提供了丰富的分区策略和扩展,以满足不同业务场景的需求。由于分区策略的实现完全由数据库内部实现,对用户是完全透明的,因此它几乎可以在实施分区表优化策略以后做平滑迁移,无需潜在耗费人力物力的应用程序更改:(1)改善查询性能,对分区对象的查询可以仅搜索自己关心的分区,提高检索效率(2)增强可用性,如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。(3)方便维护,如果分区表的某个分区出现故障需要修复数据,只修复该分区即可。常见数据库支持的分区表为范围分区表、列表分区表、哈希分区表、间隔分区、组合分区(a.w.k 组合分区)。(1)范围分区(Range Partition):将数据基于范围映射到每一个分区,这个范围是由创建分区表时指定的分区键决定的。这种分区方式是最为常用的。范围分区功能,即根据表的一列或者多列,将要插入表的记录分为若干个范围(这些范围在不同的分区里没有重叠),然后为每个范围创建一个分区,用来存储相应的数据。(2)列表分区(List Partition):将数据基于各个分区内包含的键值映射到每一个分区,分区包含的键值在创建分区时指定。列表分区功能,即根据表的一列,将要插入表的记录中出现的键值分为若干个列表(这些列表在不同的分区里没有重叠),然后为每个列表创建一个分区,用来存储相应的数据。(3)哈希分区(Hash Partition):将数据通过哈希映射到每一个分区,每一个分区中存储了具有相同哈希值的记录。(4)间隔分区(Interval Partition):可以看成是范围分区的一种增强和扩展方式,相比之下间隔分区定义分区时无需为新增的每个分区指定上限和下限值,只需要确定每个分区的长度,实际插入的过程中会自动进行分区的创建和扩展。间隔分区在创建初始时必须至少指定一个范围分区,范围分区键值确定范围分区的高值称为转换点,数据库为值超出该转换点的数据自动创建间隔分区。每个区间分区的下边界是先前范围或区间分区的非包容性上边界。(5)二级分区(Sub Partition,也叫组合分区)是基本数据分区类型的组合,将表通过一种数据分布方法进行分区,然后使用第二种数据分布方式将每个分区进一步细分为子分区。给定分区的所有子分区表示数据的逻辑子集。常见的二级分区组合由Range、List、Hash组成。分区表对查询性能最大的贡献是分区剪枝优化技术,数据库SQL引擎会根据查询条件,只扫描特定的部分分区。分区剪枝是自动触发的,当分区表查询条件符合剪枝场景时,会自动触发分区剪枝。根据剪枝阶段的不同,分区剪枝分为静态剪枝和动态剪枝,静态剪枝在优化器阶段进行,在生成计划之前,数据库已经知道需要访问的分区信息;动态剪枝在执行器阶段进行(执行开始/执行过程中),在生成计划时,数据库并不知道需要访问的分区信息,只是判断“可以进行分区剪枝”,具体的剪枝信息由执行器决定。注意,分区表由于相比普通表多了一层分区选择的处理逻辑,一般而言在数据导入场景下会有一定的性能损耗。3.9 列式存储和向量化引擎传统关系型数据库中对数据模式都是以元组(记录)的形式进行理解和存取,但是在大数量偏分析类的OLAP应用场景中,属于以列方式存储能够获得更高的执行效率,GaussDB Kernel支持行存储和列存储两种存储模型,用户可以根据应用场景,建表的时候选择行存储还是列存储表。一般情况下,如果表的字段比较多(大宽表),查询中涉及到的列不是很多,适合列存储;如果表的字段个数比较少查询大部分字段,那么选择行存储比较好,以下是行存表、列存表在存储模型上的对比。可以看到通常在大宽表、数据量比较大的场景中,查询少数特定的列、行时,行存引擎查询性能比较差。例如单表有200~800个列,经常查询访问的仅其中10个列,在这种情况下,向量化执行技术和列存储引擎可以极大地提升性能,减少存储空间。向量化执行引擎针对数据的列式存储,GaussDB在执行层改进了传统的执行引擎数据流遵循一次一元组的VectorBatch模式,而向量化引擎VectorEngine将这个执行器算子数据传递、计算模型改成VectorBatch模式,这种看似简单的修改却带来非常明显的性能提升。其中的主要提升原因可以应对上面介绍的CPU架构里影响性能的几个关键因素:(1)Batch模式的函数模型在控制流的调动下,每次都需要进行函数调用,调用次数随着数据增长而增长,而一批元组的模式则大大降低了执行节点的函数调用开销,如果我们设定Batch元组数量为1000,函数调用相对于一次一元组能减少三个数量级。(2)VectorBatch模式在内部实现通过数组来表达,数组对于CPU的预取非常友好,能够让数组在后续的数据处理过程中,大概率能够在CACHE中命中。比如对于下面这个简单计算两个整形加法的表达式函数(其代码仅为了展示,不代表真实实现),下面展示了单元组和VectorBatch元组的两种写法。单元组的整形加法int int4addint4(int4 a, int b){return a+b;}VectorBatch模式的整型加法void int4addint4(int4 a[], int b[], int res[]){for(int i = 0; i < N; i++){res[i] = a[i] + b[i];}}(3)VectorBatch模式计算函数内部因为CPU CACHE的局部性原理,数据和指令的cache命中率会非常好,极大提升处理性能,同时也为数据数组化的组织方式为利用SIMD特性带来了非常好的机会,SIMD能够大大提升在元组上的计算性能,还是以刚才上述整形加法的例子,我们可以重写上述的函数如下。可以看到,由于SIMD可以一次处理一批数据,循环的次数衰减,性能能得到进一步提升。void int4addint4SIMD(int4 a[], int b[], int res[]){for(int i = 0; i < N/SIMDLEN; i++){res[i..i+SIMDLEN] = SIMDADD(a[i..i+SIMDLEN], b[i..i+ SIMDLEN];}}在当前GaussDB里向量化引擎和普通行存引擎共存对上上层用户透明,行引擎处理单元TupleSlot与向量化引擎处理单元VectorBatch通过行转列Row2Vec、列转行Vec2Row进行在线转换,因此在复杂查询中涉及到行存、列存表时优化器能够结合代价模型并针对一些典型场景判断使用向量化引擎、行存引擎进行处理将资源利用最大化。3.10 SMP并行执行GaussDB Kernel的SMP并行技术是一种利用计算机多核CPU架构来实现多线程并行计算,以充分利用CPU资源来提高查询性能的技术。在复杂查询场景中,单个查询的执行较长,系统并发度低,通过SMP并行执行技术实现算子级的并行,能够有效减少查询执行时间,提升查询性能及资源利用率。SMP并行技术的整体实现思想是对于能够并行的查询算子,将数据分片,启动若干个工作线程分别计算,最后将结果汇总,返回前端。SMP并行执行增加数据交互算子(Stream),实现多个工作线程之间的数据交互,确保查询的正确性,完成整体的查询。并行技术是提升数据库处理能力的有效手段,关于并行技术GaussDB总体升分成了两个大类:(1)提升单节点ScaleUp:决定整体系统的理论性能上限,充分发挥单节点CPU、内存资源的对业务输出的贡献程度。(2)提升分布式ScaleOut:决定整体系统的实际性能上限,分布式实现的好坏决定了横向的线性扩展比。SMP对称多处理的实现过程:(1)SMP计划生成:一阶段计划生成:在路径生成阶段,加入并行路径,最终根据代价,决定所选择的计划两阶段计划生成:第一步生成原有的串行计划,第二步在将串行计划改造成适应并行的计划。(2)SMP执行过程:为并行执行线程之间进行数据分配、交换和汇总(Scan类:磁盘;stream:网络)。SMP对称多处理自适应选择SMP优化执行对当前执行的资源环境因素相关,因此 不同的硬件环境、不同系统负载的情况下可用的计算资源存在差异,不同时刻特定查询复杂度需要的计算资源也存在不同;自适应SMP目标在于基于当前系统可用资源以及可生成SMP计划的情况,综合判定查询的执行计划。SMP自适应分为两个阶段,第一阶段确定初始dop,第二阶段对基于初始dop生成的计划进行优化。在第一阶段考虑CPU资源、串行还是并发。在第二阶段考虑计划复杂程度。(1)资源情况:CPU core:服务器CPU core 数量 / 服务器部署DN数量;串行/并发:可用CPU core * (1 – CPU usage)。(2)查询复杂度:执行计划被stream算子拆分成多个片段,每个片段由一个线程执行。该计划中,有多少stream可以无阻塞的运行,决定了整个计划的最大并行线程数。采用特征匹配来识别查询复杂度。以上内容从USTORE存储引擎、计划缓存计划技术、数据分区与分区剪枝、列式存储和向量化引擎、SMP并行执行等五方面对高性能关键技术进行了分享,下篇将从LLVM动态查询编译执行、SQL-BYPASS执行优化、线程池化、多核处理器优化、日志无锁刷新与多级流水等方面继续解读GaussDB高性能关键技术,并对高斯数据库性能优化进行总结,敬请期待!
  • [问题求助] 外网访问 Gaussdb HA port 8001端口,放开了安全组限制还是报错
    报错信息:外网访问 Gaussdb8 HA port 8001端口,放开了安全组限制,还是报错,org.postgresql.util.PSQLException: FATAL: no gs_hba.conf entry for replication connection from host "115.204.12.51", user "root", SSL off         at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:525)         at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:146)         at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:206) 疑问:没有找到地方能让我修改 gs_hba.conf 文件放开外网ip访问数据库replication connection限制
总条数:1666 到第
上滑加载中