-
如果通过 UGO 做完表结构校验 , 并已将表结构迁移到 GaussDB 中 , 如何通过 UGO 导出已经成功的表结构
-
在数据库世界里,查询重写是提升性能的关键环节。WeTune作为一款革命性工具,能自动发现新重写规则,打破现有系统依赖人工发现重写规则的局限,大幅提升数据库查询性能。上海交通大学软件学院副院长王肇国和高斯实验室GaussDB数据库优化器专家Ethan联手开展了一场以《智能优化揭秘——GaussDB数据库查询重写的自动挖掘与生成》为主题的技术对谈,深入探讨了WeTune 2.0的重写规则与GaussDB的合作落地。直播过程包含对WeTune 2.0的项目背景、WeTune改写规则的自动发掘方式及实现、WeTune 2.0版本优势、在GaussDB中的应用与技术转化、未来前景等内容的解析与分享,一起倾听他们产教融合背后的故事吧。目录一、WeTune产品的项目背景二、WeTune改写规则的自动发掘方式三、WeTune改写规则的自动挖掘实现四、WeTune 2.0版本优势五、WeTune 2.0在华为云GaussDB的落地六、如何解决引入大量规则之后产生的性能问题?七、WeTune在数据库产业的价值及未来前景一、WeTune产品的项目背景 查询改写是数据库SQL优化过程中非常重要的部分,在语义不变的情况下,它可以把一条普通的或者性能不好的SQL语句优化成一条性能更好的SQL语句,实现查询效率的提升。改写规则作为查询改写中最关键的一个组件,想要在数据库里面添加改写规则,往往依赖于数据库专家经验的积累。如今,SQL语句的生成对象不再受限于程序员,外部框架和大模型也能够自动生成,随着生成源的增加,原来的SQL改写规则不再适用。由上海交通大学软件学院副院长王肇国团队开发出的WeTune刚好能解决这一问题,其核心思想就是自动发掘某些场景下的改写规则。于是,华为云数据库GaussDB团队与王肇国教授团队深度合作,成功完成WeTune 2.0在GaussDB产品上的落地。二、WeTune改写规则的自动发掘方式 自动挖掘的前提是暴力枚举,枚举之后检验语义是否正确,通过等价性验证去把最后一道关,所以,WeTune的等价性验证能力决定了它能够枚举哪些规则。下面是WeTune的改写规则的自动发掘方式:方式一,尝试暴力枚举所有在语法上合法的改写规则;方式二,用形式化验证的方式去验证枚举的规则是否正确(输入、输出的SQL是否在语义上等价);方式三,借鉴数据库cost estimation技术检验改写规则是否有效,SQL优化性能是否更好。在实际运用中,以上改写规则的三种自动发掘方式也面临着一些现实层面的挑战。第一个暴力枚举虽然空间大,但开销也大,导致很多算力浪费。不过,上海交通大学软件学院副院长王肇国团队通过开发的一种只枚举小规则的技术,用小规则去推大规则,解决算力浪费的问题。第二个等价性验证。改写规则等价性验证,本质上就是SQL等价性验证,把不可判定问题的验证转换成可满足性等价、可判定问题的验证。另外,SQL等价性本身是一个关系型代数,把它转换成线性代数的求解。通过这两个维度解决了现有的SQL等价性验证问题,使得改写规则的枚举能力和范围大大提升。目前WeTune 2.0支持SQL:1999所有语法的验证。第三个除了借鉴数据库cost estimation技术来检验SQL优化性能是否更好以外,还会创建数据库实例,将改写规则在数据库实例上运行,以保证SQL优化效果最佳。有了这三方面的解决方案之后,2022年,上海交通大学软件学院副院长王肇国团队对WeTune 1.0版本进行了一个性能测试。他们从GitHub上通过对起始时间、受欢迎程度等维度进行筛选排序,找了涵盖电商、论坛等不同应用场景的20个开源应用,并在这些应用上运行程序,共收集了大概8500多条SQL语句。结果显示,WeTune 1.0优化的SQL语句大概674条,而其他商业数据库只能优化427条。相较而言,WeTune 1.0 优化效果大幅领先。三、WeTune改写规则的自动挖掘实现 WeTune 2.0在SQL等价性验证、枚举的能力和范围、规则的表达上都进行了精心设计,对GaussDB使用体验有极大提升。四、WeTune 2.0版本优势 相比WeTune 1.0版本,WeTune 2.0版本有几个比较大的优势:第一,增强的WeTune枚举能力,包括枚举的速度和枚举更多的复杂规则;第二,增强的WeTune验证能力,可以支持更多的SQL特性;第三,可以让用户可读、可加载、甚至可以直接使用手写。对比现有基于代码的查询引擎,WeTune 2.0不需要代码、不需要编译、不需要去发布版本,客户自己可以写改写规则,写完之后,通过GaussDB提早准备的接口,直接放到数据库里面就可以即时生效。GaussDB可以为用户提前预留好很多重写规则,后续如发现重写规则不够用,可自行增加,非常方便。第四,改写规则可在客户端实现部署。WeTune目前主要部署在云端,后面改写规则也可以部署在客户端,进行自动加载,实现不同用户间互不干扰。五、WeTune 2.0在华为云GaussDB的落地 WeTune和现有数据库应用落地过程中,不同的架构会面临不同挑战。WeTune 2.0在华为云GaussDB的落地,从技术角度来讲,GaussDB数据库是System-R架构,它的重写规则是耦合在代码里面,增加或卸载一个规则需要改写查询引擎。把WeTune应用在System-R架构上面涉及到理论、技术、工程层面的一些问题。不过,上海交通大学和华为的积极交流和深入探讨,也为彼此提供了不同的视角。在数据库开发过程中,改写规则非常依赖人工经验。随着客户场景越来越多,很多规则已经超出了现有的承载能力。从产品开发流程层面上讲,想要在GaussDB里面添加一个新的重写规则,论证重写规则是否等价是非常困难的。但是有了WeTune以后,开发者只要按照形式化语言去描述重写规则,然后WeTune拿去做验证,证明该规则在约束下是等价的,就可以放心地将该重写规则添加到GaussDB中,节约验证时间,对GaussDB的开发等流程非常有帮助。WeTune从框架上去解决了这两个重写规则是否等价的问题,这是WeTune非常突出的贡献点。对于客户来说,在使用GaussDB进行SQL优化时,只管放心用,优化交给GaussDB;对于开发者来说,只需要关心SQL语义,性能交给GaussDB。GaussDB引入WeTune2.0以后,自然会产生非常多的规则,帮助用户优化SQL的同时,也引入了另外一个成本,即会产生了SQL优化代价。六、如何解决引入大量规则之后产生的性能问题? 从客户角度来讲,很多业务其实是相对比较固定的,而且上线之前也提前会做系统测试。若系统里面SQL优化度很高,那么就不必改写规则和暴力枚举,这样就可以降低优化成本。在实际环境中,大家希望数据库有成千上万条的改写规则可以给用户去用,可以生成改写的SQL语句。但是,改写规则非常多的时候,会导致改写和规则匹配的时间非常长,导致资源的极大浪费,也会影响用户体验。那如何在性能上做加速呢?目前来讲,主要通过两方面来去解决:一方面是从通用的匹配算法入手。当改写规则非常多的时候,匹配算法能够帮助性能有数量级的提升;另一方面,从应用的场景或从SQL产生的源头来进行分类。不同应用场景下、不同业务目的、不同的框架需要的改写规则不一样,WeTune 2.0可以对于不同场景和需求来去做定制化的规则探索。七、WeTune在数据库产业的价值及未来前景 WeTune是多个技术合起来形成了一个规则挖掘。从学术角度来讲,SQL等价性验证可以往数据库测试这个方向再迈一步。在数据库测试过程中,对于SQL的优化引擎,可以使用差分测试。差分测试是一种很经典的数据库测试方式,验证重写规则可以使用,验证SQL优化引擎过程中也适用。WeTune等价性验证器可以去枚举语义等价但形式完全不同的两条SQL,这样可以确保在测试对比过程中,程序运行是不一样的路径,可以更高效或覆盖面更广地完成数据库引擎的测试任务。WeTune不仅减轻了数据库开发者或者DBA的负担,目前在教育领域里有一定的应用,WeTune等价性验证帮助国内外很多高校助教批改学生的数据库作业,减轻数据库教育工作者的工作压力。华为与高校的深度合作将持续推进,融合双方的技术优势和科研力量,共同探索数据库领域的前沿技术,培养更多高水平的数据库人才。未来,华为和上海交通大学研究团队将携手,共同突破数据库查询重写技术的瓶颈,通过持续的创新和优化,进一步提升GaussDB的查询性能和效率。我们期待更多的技术合作和探索,推动数据库技术向智能化、自动化方向发展,为广大企业和用户带来更多价值。欢迎小伙伴们交流~
-
问题描述CPU使用率高。问题现象出现CPU使用率超过阈值,CPU使用率快速上涨或短时间持续较高水平等现象。告警CPU使用率告警。业务影响CPU使用率高集群响应变慢。原因分析期间业务压力增大导致。出现CPU耗时较多的SQL。处理方法步骤 1查看监控是某个节点的CPU高还是集群整体CPU高,如果是整体CPU高生成集群级别wdr报告,如果是某个节点则生成节点级wdr报告。步骤 2首先查看当前已有的wdr报告快照。select * from snapshot.snapshot order by start_ts desc;步骤 3生成wdr报告需要两个snapshot_id,根据需要对比的两个时间段选取对应的snapshot_id,调整输出格式,gsql界面输入: \a \t \o + 生成文件名(html文件)步骤 4如果是要生成节点级的报告则执行:select generate_wdr_report(snapshot_id1, snapshot_id2, ‘all’, ‘node’, 节点名称)如果要生成集群级别报告则执行select generate_wdr_report(snapshot_id1, snapshot_id2, ‘all’, ‘cluster’)其中snapshot_id1和snapshot_id2按照时间从小到大的顺序写入上面分析出来的要生成报告的两个id,节点名称可以通过登录到问题节点执行show pgxc_node_name获取。 对应节点级别报告主要关注Top 10 Events by Total Wait Time和SQL ordered by CPU Time部分,集群级别主要关注SQL ordered by CPU Time部分,在wdr报告中搜索即可。步骤 6CPU使用率较低期间的wdr报告和较高期间的wdr报告个一份,这里已节点级别为例,集群级别只需要按照SQL ordered by CPU Time部分分析,分析方式一样。步骤 7Top 10 Events by Total Wait Time部分包含两个快照期间的主要等待事件,可以进行大致分析是否存在大量CPU耗时较高的等待事件例如文件数据读取,快照期间主要等待事件,如果通过对比发现CPU高期间的文件读事件明显变多,则说明此期间SQL执行读取数据上上涨导致的CPU耗时上涨。如果是各项等待事件都有一定幅度上涨则可能是集群压力上涨导致,具体是那一部分SQL则需要分析SQL ordered by CPU Time部分。步骤 8对比两份报告SQL ordered by CPU Time部分的CPU Time(us)差异,一般对比前10个即可,这里介绍一下此部分的主要构成。Unique SQL Id:对应unique_sql_id,可以通过此id去数据库查询使用此模板的SQL的其他数据,例如通过summary_statement查询总体语句的调用情况。Node Name:节点名称。User Name:用户名。CPU Time(us):两个快照期间的CPU耗时Calls:两个快照期间的语句调用次数。Min Elapse Time(us):SQL在内核内的最小运行时间,注意这是整体的最小解析时间不是此快照期间的最小。Max Elapse Time(us):SQL在内核内的最大运行时间,注意这是整体的最大解析时间不是此快照期间的最小。Total Elapse Time(us):两个快照期间此语句的SQL在内核内的总运行时间时间。Avg Elapse Time(us):两个快照期间此语句的SQL在内核内的平均运行时间时间。Returned Rows:两个快照期间此语句的SELECT返回的结果集行数。Tuples Read:两个快照期间访问的元组数量。Tuples Affected:两个快照期间Insert/Update/Delete行数。Logical Read:两个快照期间的逻辑读数。Physical Read:两个快照期间的物理读数。Data IO Time(us):两个快照期间IO上的时间花费。Sort Count:两个快照期间的排序执行的次数。Sort Time(us):两个快照期间的排序执行的时间。Sort Mem Used(KB):两个快照期间的排序过程中使用的work memory大小(单位:KB)。Sort Spill Count:两个快照期间的排序过程中,若发生落盘,写文件的次数。Sort Spill Size(KB):两个快照期间的排序过程中,若发生落盘,使用的文件大小(单位:KB)。Hash Count:两个快照期间的hash执行的次数。Hash Time(us):两个快照期间的hash执行的时间(单位:微秒)。Hash Mem Used(KB):两个快照期间的hash过程中使用的work memory大小(单位:KB)。Hash Spill Count:两个快照期间的hash过程中,若发生落盘,写文件的次数。Hash Spill Size(KB):两个快照期间的hash过程中,若发生落盘,使用的文件大小(单位:KB)。SQL Text:这里显示的SQL语句只有一部分,完整的SQL需要点击Unique SQL Id跳转到完整SQL处。步骤9如果发现CPU高期间报告的CPU Time(us)前面几个的SQL明显不同且CPU耗时较大,则原因可能为CPU高耗时SQL调用量上涨导致,如果需要分析为什么此SQL的CPU耗时高则可以参考步骤11。步骤 10如果两个报告前10个Unique SQL Id对比几乎相同,此时看SQL对应的CPU耗时和ncalls,如果calls上涨则说明是业务压力增大导致的CPU上涨,如果calls没有上涨,则需要分析为什么同一条SQL在此阶段的CPU耗时上涨,跳转步骤11。步骤 11在语句和调用次数没有变化的情况下,如果是查询语句看此SQL模板的Returned Rows和Physical Read,如果数量有明显增长则说明此SQL读写的数据量增大导致的CPU压力上涨,一般有两种情况,部分特殊值的情况下扫描数据量大或者计划发生改变导致扫描数据量变大。如果是写语句则可以看Tuples Affected是否有明显增加,一般读取数据比较耗CPU,如果是语句本身影响的主要围绕数据读取方面进行对比。步骤 12如果两个快照的数据几乎相同,可以通过火焰图或者长事务做进一步分析。
-
本篇为大家分享GaussDB高安全的关键特性,名字叫密态等值,是一个关于全密态的关键能力。数据成为生产要素,合规要求趋于严格 大家应该都有切身的体会,近些年数据的重要性越来越高,特别是国家已经把数据明确定义为了生产要素。生产要素是什么?就好像过去的石油,从工业革命时期开始,每一家工业企业几乎都要用到,是生产过程中必不可少的东西。现在,国家把数据定义为生产要素,意味着数据在各个领域也将要广泛地使用到。正因为这样,数据也上升成为了国家的“战略资源”。基于此,国家近些年发布了《中华人民共和国数据安全法》、《中华人民共和国个人信息保护法》等一系列法律,对数据安全的保护标准和使用规范越来越明确、越来越严格,这是我们切身体会到的一个大的趋势。数据库安全面临更大的威胁和挑战 在这种新形势下,数据库的安全也面临很大的威胁。我们做了一个梳理,从里到外,数据库的安全问题一共有以下几个方面:首先,数据安全传输从网络层面容易受到攻击。大概20年前,安全人员在网络上部署一台嗅探器,就可以获取到许多的敏感信息。而之后陆续出现相关的标准和技术,经过一段时间的演进逐步成熟,演变成稳定的安全协议或安全架构,被广泛使用起来。例如HTTPS、TLS等,通过这种安全协议上的消解,我们发现,现在很难通过网络攻击,直接获取到敏感的东西。随后我们发现,SQL注入,以及网页跨站等问题开始越来越明显,数据展示层的攻击虽然和数据库不直接相关,而是从数据库把数据拿出来之后放到业务层,在业务层引入的风险,但这些风险也可以通过数据库提供的能力进行消减,因此也纳入数据库威胁范围内。同样也是随着技术的发展,一些稳定的安全框架、安全编码规范形成之后,这部分的风险逐渐消减了。其次是存储。各类安全规范里经常会提及到存储安全保护,因为数据一旦存在磁盘里,有可能永远都在磁盘里,直到磁盘销毁的那一天。如果里面存放了敏感数据,理论上每一天都有被偷走的可能,所以存储安全非常的重要。关于这一点,相关的技术也在逐步成熟,像磁盘加密、透明加密等,而且各家机构企业也都非常重视对于物理硬件的保护,管理手段非常严格,所以磁盘被偷走的情况也很少出现。最近几年,经常看到各种各样的严重安全事件,主要在两个维度,一个是维护,一个是管理。维护就是后台操作系统的人员做一些数据库的维护操作,管理就是DBA通过数据库标准通道做一些管理操作。这也不一定是内部人员有问题,也有可能是这些内部人员的账号被泄露,近几年世界知名的一些大型数据安全事件,大部分是在这两个方面出了问题,都泄露了很多的数据,这是新形势下最大的安全威胁。GaussDB以数据为中心 构筑起3+1安全架构 面对这些挑战,GaussDB构筑起了3+1的安全架构。这个架构的最外层,是基于智能化能力做一些风险、异常行为的感知,先感知有没有恶意攻击,阻挡一遍攻击。中层是访问控制能力,加上口令、身份认证等,进一步控制用户访问风险。里层是数据加密、脱敏,直接在数据上做文章,因而攻击者即使将外层全部攻破,拿走的也全部是密文状态下的数据。最后在这三层之外是审计,GaussDB做了很多细粒度的审计能力,还有防篡改。我们的审计日志是改不了的,即使篡改了,也能看出来哪里被改了。所以,即使攻击者做了很多操作,把数据库也攻破了,但所有操作是跑不了的。而今天分享的就是全密态里面的等值查询。GaussDB全密态等值查询 实现数据全流程保护 全密态技术的原理很简单。比如在使用的时候输入一个SQL语句,加密驱动会找到哪个字段需要加密,然后用一个密钥把它自动加密,这样加密完后整个流程都是密文的,整个数据库跑的数据、以及跑完之后的结果都是密文数据,不论什么时候把数据拿走,拿走的也都是密文的,因为在整个数据库里面没有任何解密的过程。我们对查询回来的密文结果在客户端再进行解密,将明文数据返回给业务进行处理,从而能够做到无感知的使用和业务迁移。我们当前支持密态等值等查询,很快还会支持密态范围查询和模糊查询,都是基于密码学的算法。对于大规模数据,我们还可以基于密文数据进行索引和快速查询,并且支持JDBC、GO、Libpq等多种客户端驱动。客户端密钥管理,保障服务可信 对加密来说,密钥是最关键的,所以全密态最主要的是密钥的分配。我们的全密态密钥是在客户端管理,一般属于业务管理人员负责,业务管理人员拿到密钥后把数据加密再交给数据库。逻辑很简单,我们在驱动层做了一个加密驱动,里面做了自动加解密和自动解析,能够自动识别哪个字段需要哪个密钥,再自动找到密钥、自动加密。这样只要业务不把密钥权限分配给DBA和运维,他们就不能解密这部分数据,但是能够正常运维,如果有极特殊的情况需要看到明文敏感数据才能做管理运维,也可以把密钥赋权给相关人员。全流程加密,数据库内部全流程零解密 第二层是加密,数据库里的整个流程是没有解密过程的,这是GaussDB实现的最主要的能力,包括传输、查询、存储等操作都有对应的方式,不需要解密再处理。但是,如果不单是在客户端需要数据导出,假如后端也需要直接导出数据,我们也可以在某些特殊场景下把密钥授权给下游做临时解密。这是加密方面的情况介绍。客户端轻量化解析 业务层加密透明无感 另外,如何做到透明无感知?解析器是数据库里的关键组件,我们在客户端里面做了一个轻量化解析器,对用户输入进去的SQL语句做自动的语法解析,找到哪个字段需要加密,而对于返回过来的语法也进行对应的解析。做完这个解析,客户端可以获取到需要加密的数据以及该数据在原始语句中的位置,然后重新构造一个新的SQL语句,数据库实际收到的就是加密之后的数据。经过客户端的自动语法解析,自动密钥管理和自动加密后,就可以继承标准的SQL语法,实现业务的透明无感知。对于业务迁移,也只需要修改一下建表语句,配置数据加密的表和加密字段即可,在实际增删改查过程中,所有操作语句都是与明文一样的。全密态等值和传统加密有什么区别?我做了一个总结。应用案例 自己生产的降落伞自己先跳,GaussDB的全密态能力已经在华为的MetaERP系统商用了。不久前,华为宣布实现自主创新的MetaERP研发,完成对旧ERP系统的替换,目前已覆盖了华为公司100%的业务场景和80%的业务量。ERP作为华为企业经营最核心的系统,伴随着华为20多年的快速发展,支撑了每年数千亿产值的业务以及全球170+国家业务高效经营。我们分析过一个业务,其中有270多个绝密字段,任何一个环节发生数据泄露都是重大事故。而之前的传统方案,是强制在应用层加密,加密完成后存到数据库,用数据的时候,先把数据查询出来之后做解密再使用,数据库做不了任何事情,这种方案加密时间长,性能损耗大,密钥需要自管,所以上了全密态。刚开始做自己的ERP系统的时候,数据库的容量、性能,特别是对批量数据的查询和处理,都是空前挑战。因为ERP业务实际是不看TPCC等基准测试指标的,他们只看实际业务场景的性能,比如批量插入、批量查询等,这给我们提供了一个良好的训练场,我们对批量处理性能等多种场景的实际应用都进行很大的优化,确保MetaERP在全密态下能满足业务对性能的要求。另外,ERP应用的时候有一个特点,交易查询完之后,下游还有一个分析库处理,我们有一个密钥授权能力,在业务负责人将密钥权限授权下游处理节点后 ,数据库就把密文数据解密后托管给下游处理,这样后台数据就可以不经过客户端,不同的应用只需要使用同一个KMS(密钥管理)就可以操作同一部分数据。另外,只要业务负责人不把密钥授权给其他任何人,就没有人能处理这个数据,包括管理和运维人员。最后是获得的一些成绩,GaussDB是国内首个通过国际CC EAL4+认证的数据库,也是国内首批通过信通院全密态数据库评测、国内首家通过信通院防篡改数据库评测的数据库产品。今天的分享就到这里,欢迎小伙伴们一起交流。
-
本篇为大家分享GaussDB性能调优的实践。主要包括三个部分,分别是性能调优的整体介绍,性能调优的关键技术,性能调优的应用实践。GaussDB性能调优简介 我们知道数据库作为系统软件,在整个计算机体系中起到关键的承上启下作用。可以看到应用程序通过北向接口与数据库进行交互,数据库通过南向接口与操作系统和硬件进行交互。对于数据库系统的性能影响是多方面的,不管是硬件规格、操作系统配置、数据库系统的设计、应用和客户端的连接方式,都会对业务最终的性能表现产生很大的影响,所以数据库的性能表现本质上是整体计算机系统软硬件协调的结果。数据库性能优化充满复杂性和挑战性,既有主观的成分,也有复杂的一面。性能问题的主观性,举例来说,某个查询消耗是1s,它的性能是好还是坏,是否脱离业务目标很难讲清楚。所以描述性能问题时要目标清晰、描述具体、结果可度量。例如一个问题出现后,需要给出硬件配置、参数信息、部署形态、业务场景、当前结果、期望目标等信息。另一个面临的性能问题是复杂性,通过一个问题表象,很难一眼判断是哪个模块引起的,需要分析出一个明确的方向,进一步观察作业在不同模块间数据流动,用全局视角来分析问题;如果性能问题不是单点的问题,我们需要从中找到引起问题的主要矛盾,然后先解决掉大头,看看是否满足业务诉求。在遇到数据库性能相关问题时,经常会出现一些行业术语。比如:IOPS通常指数据库系统数据盘每秒读写IO的次数,反映了磁盘IO的读写能力;吞吐量,往往指的是数据库每秒处理事务数TPS或者查询数QPS,反映整体的负载状况;响应时间,指的是数据库中一条查询从发起到结果返回的时间开销,用来识别慢SQL;饱和度,指大并发场景下属于工作队列的任务数,反映当前系统作业被积压的情况,以及忙闲程度。GaussDB数据库的逻辑架构分析GaussDB性能问题前,先简单介绍一下其逻辑架构,主要包括以下组件:GaussDB数据库的查询处理流程了解GaussDB架构后,我们简单梳理一下查询处理流程,拆解到每个模块,展开一下每个模块的功能和性能关注点。GaussDB性能调优关键技术 下面介绍一下GaussDB在性能优化方面的几个关键技术。计划缓存计划缓存技术,一般在OLTP的业务负载中,因为涉及的数据量较少,通过索引加速数据访问路径后,查询解析、重写、优化占比就很高。对于模板行的语句,可以将模板语句的计划缓存起来,那么同模板不同参数语句执行时,可以直接使用缓存计划,大大提升并发吞吐量。我们设想一下,缓存计划是针对一个session,还是针对整个系统的,由此引申出两个概念,local plan cache和global plan cache。如果只在session上缓存已执行计划,可能会导致每个session上执行计划都很多,占用内存资源较高,GPC可以很好解决内存占用问题,但维护代价较大,管理成本高。还有一个问题是,缓存计划可能针对某一类SQL,如果参数变化后,执行计划不优怎么办。GaussDB实现了计划自适应选择的能力,可以自动为不同参数配置最佳的缓存计划。智能基数估计智能基数估计主要解决两个问题:一是什么时候创建多列统计信息?二是创建什么类型的统计模型?当前常见的方案是采用MCV(一种软件架构模式)和直方图的统计模型来实现。但这两个方案在单列场景估计的比较准确,在多列场景中仅支持单表,而且误差较大,无法应用。GaussDB创新性地设计出基于库内轻量级贝叶斯网络算子模型来实现多列场景下的基数估计;基于DB4AI的轻量级算子,在数据库内完成训练和推理,对内核几乎无影响;在自动analyze收集统计信息时,自动创建贝叶斯网络模型;优化器在进行多列基数估计时,调用训练好的模型,给出准确率的数值。分布式查询执行GaussDB分布式数据库在查询执行过程中,采用多种技术提升查询执行的性能。其中分布式执行框架用于实现分布式集群的多节点并行处理能力,提升集群整体的性能。在复杂语句查询时,会将重执行算子下推到DN节点执行,例如AGG算子等。在下推算子执行时,会考虑数据本地性,尽可能在本地计算,减少数据在网络中的传输开销,从而提升数据库整体的查询性能。在单节点内,通过SMP并行技术,利用多核CPU的并行加速,结合内存管控,提升单节点的性能。GTM LiteGTM负责全局事务的一致性。传统的GTM组件需要维护每一个活跃事务信息,作业执行时,需要从GTM获取快照时,拿到的是当前的活跃事务链表,如果量特别大,将对网络并发带来压力。GaussDB实现GTM lite能力,通过CSN号代替事务链表,获取的快照仅为CSN号,在事务提交时,也只需要原子加CSN号。在可见性判断时,基于CSN号进行,如果事物结束的CSN比快照中CSN值小,那么元组可见,否则元组不可见。日志并行流水线数据库日志系统非常关键,是数据持久化的关键保证。因为日志有顺序依赖关系,所以传统数据库一般采用串行刷日志的设计。GaussDB采用log writer日志写盘线程并行写机制,充分发挥多通道IO的能力。GaussDB日志并行流水线主要机制是将一把大锁,拆分为多个并行的小锁,部分worker线程的事务日志写到一个事务日志共享缓冲区,每个事务结束前保证对应的事务日志LSN已经刷盘,有全局LSN原子加保证顺序。NUMA AwareGaussDB在多核ARM架构下,通过NUMA Aware技术解决跨NUMA内存访问延迟问题。我们主要做了以下动作:全局数据结构NUMA化改造,关键数据结构包括CLOG、Wal insertlock、proc array等,降低了数据访问延迟;将内核工作线程与NUMA Node进行绑定,避免跨NUMA调度;利用原子操作指令集LSE,提升计算性能。GaussDB性能调优应用实践 最后介绍性能调优的应用实践。先看看性能调优的思路,遇到性能问题,先确定性能调优的范围,观察是否是某个系统资源达到瓶颈,或者是否存在SQL阻塞或慢SQL。如果是系统资源类问题,通过系统调优来进行诊断和优化;如果是SQL层面问题,通过SQL调优进行诊断和优化,最终看优化后效果是否满足业务需求,如果一次优化不能达成预期,则需要多轮迭代,最终达成目标。数据库系统整体性能问题的定位思路,先判断是数据库层面问题还是其他层面问题,其他层面问题是否是节点上其他进程引起的数据库性能下降,或者是操作系统参数配置不当引起的。若是数据库层面问题,需要对数据库占用的系统资源信息、数据库内核资源、主备状况等进行综合分析,最后确认问题根因。在分析单条SQL语句性能时,可以通过使用视图statement_history或者statement,查询语句每个阶段执行的时间消耗,确定语句执行的性能瓶颈。statement_history记录了执行时间超过阈值(log_min_duration_statement,默认3 s)的详细SQL信息,包含计划生成时间、执行时间、锁等待时间等信息;statement记录了SQL按照unique_sql_id归一化的执行信息,包括执行次数、总的执行时间、访问数据量、内存使用等信息。然后通过等待事件视图,查询阻塞会话和对象;最后通过执行计划,获取更细粒度的算子执行情况,如是否走索引、走正确的索引、分布式执行算子stream是否涉及广播等。讲到GaussDB全量SQL和慢SQL,他们包含哪些内容。GaussDB的多维度指标监控采集粒度不同,对系统性能的影响也不同,主要分为三个级别进行采集。下面介绍两个案例。第一个是应用升级后引起了性能剧烈波动,我们先观察一下实例整体执行的时间,看看在哪一步消耗的比重最高,通过归一化视图观察单个SQL,看每一步的执行消耗,发现是在网络发送部分引起的,我们把应用侧进行替换,应用程序更新后这个问题就解决了。第二个是集群整体性能劣化。我们先观察CN上线程等待状态,发现有些节点等待次数超高;在异常节点上分析等待事件,发现wal sync等待的时间较高,通过对比正常节点,确认该节点上存在wal sync的问题;最后分析出主备间日志LSN分片差异较大,一直在进行回放,影响系统整体性能。最后介绍一下GaussDB两个自调优利器,分别是索引推荐和分布键推荐,主要用于提供高效推荐。比如索引推荐,可以帮助用户根据业务负载自动推荐合适的索引组合,识别冗余索引和无效索引;在推荐索引时,同时输出正向提升SQL信息和负向提升SQL信息,帮助用户来决策是否使用推荐的索引。本篇分享就到这里,谢谢大家。
-
本篇将分享GaussDB数据库迁移的创新实践。易迁移能力是企业数据库替换选型的关键考量 数据库的选型除了要看数据库本身的能力外,能否很平滑地从其他数据库迁移到GaussDB,也是很多企业考量的关键因素。而数据库能否平滑迁移有两个非常核心的要素,一个是数据库本身,比如能否很好地兼容主流数据库的语法,让应用少改或者不改;另外一个是在数据库外围能否提供一些好用、易用的迁移工具,把应用中内嵌的SQL、数据库中的对象以及全量和增量数据,在业务近乎零停机的情况下从其他数据库平滑地迁移过来。这两点是企业做数据库选型时考量的两个迁移关键要素。结构(UGO)+数据(DRS) 一站式迁移解决方案在2021年的DTCC大会上,发布了华为云结构+数据一站式迁移解决方案,其中有两个核心工具。一个工具是UGO,主要做结构和应用的语法兼容性评估和转换,比如将数据库上层应用中内嵌的SQL捕获出来进行评估,对数据库内部对象的DDL进行评估,并输出一个报告,清晰地展示哪些是数据库本身兼容的、哪些是通过UGO转换可以兼容的、哪些不能转换需要人工介入进行改造等。另外一个工具是DRS,大家都知道,异构数据库替换过程中的数据迁移问题非常非常多,DRS要解决的就是怎么在业务近乎不停机的情况下快速把客户的存量数据和增量数据迁移过来,并保证数据在任何情况下不丢、不错、不乱,同时提供灵活、多样的数据比对和修复能力。UGO+DRS一体化解决方案 在实际项目中得到验证UGO+DRS一站式迁移解决方案近两年在很多项目中都得到了验证和应用,这里举几个实际的例子。第一个是我们公司自己内部的MetaERP项目,使用UGO自动转换了近7亿行的O数据库SQL脚本,转换成功率接近100%,同时GaussDB实现了并行逻辑解码,性能高达近300MB/秒,可以让DRS轻松应对MetaERP在月结、季结和年结时10~20倍的流量洪峰,保证数据同步<5s的低时延。第二个是某银行的数据库替换,这个项目迁移复杂度比较高,面临应用多、数据库对象多、存储过程和package深度依赖等困难,截至目前通过我们的一站式迁移解决方案,完成了近1.3亿行SQL脚本(包含近8000万存储过程)的UGO自动转换,转换成功率超过96%,采用DRS迁移了近300套左右的O数据库实例,实现了O数据库与GaussDB数据库的长时间并机稳定运行,正反向低时延数据同步。项目实施过程中遇到新的困难与挑战 在大量的项目实施过程中,UGO+DRS一站式迁移解决方案也遇到了一些新的困难和挑战,这些挑战相信大家也都会遇到,在此给大家做个分享。挑战一在做异构数据库替换时,如何快速识别异构数据库语法不兼容点,识别数据相同的情况下相同SQL在不同数据库中执行的性能差异,以及低版本向高版本升级时是否会存在不兼容或性能劣化,再有就是如何模拟业务流量洪峰时的数据库行为表现。挑战二当前很多企业的开发人员和DBA对GaussDB熟悉程度还不高,SQL编写水平参差不齐,而且在做应用开发时缺乏统一的SQL编程规范和有效的SQL审核机制,很多烂SQL都流入了生产环境,进而引发大量的应用性能问题,影响生产业务和客户体验。挑战三很多数据库当前的字符集在标准字符集的基础上做了很多扩展或者定制,导致数据迁移时相同字符集的不兼容,或者就没有对等的字符集,更有甚者,历史数据里已经存在了各种各样的乱码数据,这些特殊场景都会影响迁移的平滑性。当然,困难和挑战还有很多,但这三个是会阻塞或拖慢数据库迁移进程的,那么针对这三个挑战,我们都做了哪些探索和创新呢?再给大家分享一下。应对挑战一:孵化数据库流量录制与回放能力流量录制与回放的概念相信大家都不陌生,在数据库领域,有些数据库厂商也提供了相应的工具,GaussDB面临的业务场景比较多,所以需要的技术也因场景而异。如果源数据库是公有云服务,而且提供了全量SQL,那么直接获取全量SQL并进行回放即可;如果源数据库开启了审计日志,也可以直接下载并解析审计日志,当然开启审计日志会对数据库的性能有一定的影响;如果源端是自建数据库,而且未开启审计日志,那就需要部署一个agent,通过捕获网络数据包,结合数据库本身的通信协议来解析出应用下发的所有SQL。基本上这三种方案可以涵盖所有的场景,这里面还要注意几个点,首先是要研究透不同数据库的通信协议,其次是实现异构数据库替换场景下的SQL自动转换,另外是要具备SQL回放的流量控制能力,能加速或者放慢等,当然在解析、回放等出现异常的情况下,要做好记录。接下来就是在源数据库的镜像库和GaussDB数据库同时进行流量回放,而且保证镜像库和目标数据库的数据完全一致,回放的SQL也完全一样,最终输出一个分析报告,比对每一条SQL的执行耗时、资源消耗、甚至是执行结果,很容易看出来哪些SQL的性能GaussDB比源数据库好、哪些出现了劣化、哪些是基本持平的。GaussDB团队正在和某银行进行数据库流量录制与回放的联合创新,从实际应用效果来看,通过agent方式捕获流量包,SQL抓取成功率可以做到97%以上,解析成功率和回放成功率可以达到95%,在此过程中,还可以识别到语法不兼容、语义不兼容的异常情况。应对挑战二:孵化GaussDB数据库SQL审核能力SQL审核大家更为熟悉,很多大的企业都会进行探索和实践,但对于GaussDB来说,由于是纯自主创新的分布式数据库,很多企业的开发人员和DBA还不熟悉GaussDB的SQL语法,也没有制定较为完善的SQL编程规范,很多第三方SQL审核工具也没有针对GaussDB的审核能力,这种情况下,我们结合UGO成熟的SQL解析器,以及多个项目中的SQL调优实践,孵化出了GaussDB数据库的SQL审核能力。SQL审核的输入可以有多种类型,可以是代码仓,也可以是一个SQL文件,还可以是通过流量录制获取的动态SQL等等,可以审核直接获取到的原生SQL,也可以审核通过UGO转换后的SQL。截至目前,已经沉淀了81条审核规则,并在公司内部的两个项目以及外部的多个银行进行了应用,效果超出预期。应对挑战三:孵化字符集兼容性分析评估能力针对数据迁移,大家最担心的莫过于正式割接时出现各种各样的问题导致割接失败,除了迁移工具本身的功能之外,最常见的可能就是字符集不兼容、数据乱码、生僻字等等。举个例子,O数据库对GBK字符集做了扩充,可以存储UTF-8字符,而GaussDB数据库的GBK字符集非常规范,从O数据库向GaussDB迁移数据时,这些UTF-8字符根本无法写入,迁移必然失败。更有甚者,很多客户的海量历史数据中有大量的乱码数据,无法确定这些数据是什么时候写入的,哪些应用写入的,或者后续会不会再用到,但客户要求必须迁移过来。那么,面对这些挑战,我们尝试通过孵化字符集兼容性分析评估工具来提前识别。这个工具的原理很简单,首先是建立一个可以分析的字符集基线,比如GB系、Unicode系列等,其次是获取源数据库的元数据,包括字符集、索引信息、表结构信息(列类型、列长度)等,然后基于源数据库和目标数据库的字符集做好映射,最后再对数据库进行数据扫描和分析,输出多维度的分析评估报告。目前这个工具正在和某银行进行联创,从前期的试用效果来看,确实能发现很多问题,比如ZHS16GBK和AL32UTF8两种字符集混编、直接写入二进制格式导致数据乱码、ZHS16GBK字符集使用了大量生僻字等。对UGO+DRS一站式迁移解决方案 的演进思考 以上是在使用UGO+DRS一站式迁移解决方案过程中遇到的三个大的挑战,以及应对这三个挑战做的一些创新实践。现在GaussDB的迁移场景越来越多,也越来越复杂,所以会不断地进行探索和创新,让方案更完善,迁移过程更平滑,比如流量回放、SQL审核、字符集兼容性评估会支持更多的数据库,推出非常详细和全面的应用、结构、数据迁移可行性分析报告,实现SQL捕获、转换、审核、优化全流程一体化管理等等,也希望能和客户、伙伴以及各位同行进行合作。以上是GaussDB数据库在迁移方面的一些创新实践,谢谢大家,欢迎交流。
-
本篇为大家分享GaussDB高安全的关键特性,名字叫密态等值,是一个关于全密态的关键能力。数据成为生产要素,合规要求趋于严格 大家应该都有切身的体会,近些年数据的重要性越来越高,特别是国家已经把数据明确定义为了生产要素。生产要素是什么?就好像过去的石油,从工业革命时期开始,每一家工业企业几乎都要用到,是生产过程中必不可少的东西。现在,国家把数据定义为生产要素,意味着数据在各个领域也将要广泛地使用到。正因为这样,数据也上升成为了国家的“战略资源”。基于此,国家近些年发布了《中华人民共和国数据安全法》、《中华人民共和国个人信息保护法》等一系列法律,对数据安全的保护标准和使用规范越来越明确、越来越严格,这是我们切身体会到的一个大的趋势。数据库安全面临更大的威胁和挑战 在这种新形势下,数据库的安全也面临很大的威胁。我们做了一个梳理,从里到外,数据库的安全问题一共有以下几个方面:首先,数据安全传输从网络层面容易受到攻击。大概20年前,安全人员在网络上部署一台嗅探器,就可以获取到许多的敏感信息。而之后陆续出现相关的标准和技术,经过一段时间的演进逐步成熟,演变成稳定的安全协议或安全架构,被广泛使用起来。例如HTTPS、TLS等,通过这种安全协议上的消解,我们发现,现在很难通过网络攻击,直接获取到敏感的东西。随后我们发现,SQL注入,以及网页跨站等问题开始越来越明显,数据展示层的攻击虽然和数据库不直接相关,而是从数据库把数据拿出来之后放到业务层,在业务层引入的风险,但这些风险也可以通过数据库提供的能力进行消减,因此也纳入数据库威胁范围内。同样也是随着技术的发展,一些稳定的安全框架、安全编码规范形成之后,这部分的风险逐渐消减了。其次是存储。各类安全规范里经常会提及到存储安全保护,因为数据一旦存在磁盘里,有可能永远都在磁盘里,直到磁盘销毁的那一天。如果里面存放了敏感数据,理论上每一天都有被偷走的可能,所以存储安全非常的重要。关于这一点,相关的技术也在逐步成熟,像磁盘加密、透明加密等,而且各家机构企业也都非常重视对于物理硬件的保护,管理手段非常严格,所以磁盘被偷走的情况也很少出现。最近几年,经常看到各种各样的严重安全事件,主要在两个维度,一个是维护,一个是管理。维护就是后台操作系统的人员做一些数据库的维护操作,管理就是DBA通过数据库标准通道做一些管理操作。这也不一定是内部人员有问题,也有可能是这些内部人员的账号被泄露,近几年世界知名的一些大型数据安全事件,大部分是在这两个方面出了问题,都泄露了很多的数据,这是新形势下最大的安全威胁。GaussDB以数据为中心 构筑起3+1安全架构 面对这些挑战,GaussDB构筑起了3+1的安全架构。这个架构的最外层,是基于智能化能力做一些风险、异常行为的感知,先感知有没有恶意攻击,阻挡一遍攻击。中层是访问控制能力,加上口令、身份认证等,进一步控制用户访问风险。里层是数据加密、脱敏,直接在数据上做文章,因而攻击者即使将外层全部攻破,拿走的也全部是密文状态下的数据。最后在这三层之外是审计,GaussDB做了很多细粒度的审计能力,还有防篡改。我们的审计日志是改不了的,即使篡改了,也能看出来哪里被改了。所以,即使攻击者做了很多操作,把数据库也攻破了,但所有操作是跑不了的。而今天分享的就是全密态里面的等值查询。GaussDB全密态等值查询 实现数据全流程保护 全密态技术的原理很简单。比如在使用的时候输入一个SQL语句,加密驱动会找到哪个字段需要加密,然后用一个密钥把它自动加密,这样加密完后整个流程都是密文的,整个数据库跑的数据、以及跑完之后的结果都是密文数据,不论什么时候把数据拿走,拿走的也都是密文的,因为在整个数据库里面没有任何解密的过程。我们对查询回来的密文结果在客户端再进行解密,将明文数据返回给业务进行处理,从而能够做到无感知的使用和业务迁移。我们当前支持密态等值等查询,很快还会支持密态范围查询和模糊查询,都是基于密码学的算法。对于大规模数据,我们还可以基于密文数据进行索引和快速查询,并且支持JDBC、GO、Libpq等多种客户端驱动。客户端密钥管理,保障服务可信 对加密来说,密钥是最关键的,所以全密态最主要的是密钥的分配。我们的全密态密钥是在客户端管理,一般属于业务管理人员负责,业务管理人员拿到密钥后把数据加密再交给数据库。逻辑很简单,我们在驱动层做了一个加密驱动,里面做了自动加解密和自动解析,能够自动识别哪个字段需要哪个密钥,再自动找到密钥、自动加密。这样只要业务不把密钥权限分配给DBA和运维,他们就不能解密这部分数据,但是能够正常运维,如果有极特殊的情况需要看到明文敏感数据才能做管理运维,也可以把密钥赋权给相关人员。全流程加密,数据库内部全流程零解密 第二层是加密,数据库里的整个流程是没有解密过程的,这是GaussDB实现的最主要的能力,包括传输、查询、存储等操作都有对应的方式,不需要解密再处理。但是,如果不单是在客户端需要数据导出,假如后端也需要直接导出数据,我们也可以在某些特殊场景下把密钥授权给下游做临时解密。这是加密方面的情况介绍。客户端轻量化解析 业务层加密透明无感 另外,如何做到透明无感知?解析器是数据库里的关键组件,我们在客户端里面做了一个轻量化解析器,对用户输入进去的SQL语句做自动的语法解析,找到哪个字段需要加密,而对于返回过来的语法也进行对应的解析。做完这个解析,客户端可以获取到需要加密的数据以及该数据在原始语句中的位置,然后重新构造一个新的SQL语句,数据库实际收到的就是加密之后的数据。经过客户端的自动语法解析,自动密钥管理和自动加密后,就可以继承标准的SQL语法,实现业务的透明无感知。对于业务迁移,也只需要修改一下建表语句,配置数据加密的表和加密字段即可,在实际增删改查过程中,所有操作语句都是与明文一样的。全密态等值和传统加密有什么区别?我做了一个总结。应用案例 自己生产的降落伞自己先跳,GaussDB的全密态能力已经在华为的MetaERP系统商用了。不久前,华为宣布实现自主创新的MetaERP研发,完成对旧ERP系统的替换,目前已覆盖了华为公司100%的业务场景和80%的业务量。ERP作为华为企业经营最核心的系统,伴随着华为20多年的快速发展,支撑了每年数千亿产值的业务以及全球170+国家业务高效经营。我们分析过一个业务,其中有270多个绝密字段,任何一个环节发生数据泄露都是重大事故。而之前的传统方案,是强制在应用层加密,加密完成后存到数据库,用数据的时候,先把数据查询出来之后做解密再使用,数据库做不了任何事情,这种方案加密时间长,性能损耗大,密钥需要自管,所以上了全密态。刚开始做自己的ERP系统的时候,数据库的容量、性能,特别是对批量数据的查询和处理,都是空前挑战。因为ERP业务实际是不看TPCC等基准测试指标的,他们只看实际业务场景的性能,比如批量插入、批量查询等,这给我们提供了一个良好的训练场,我们对批量处理性能等多种场景的实际应用都进行很大的优化,确保MetaERP在全密态下能满足业务对性能的要求。另外,ERP应用的时候有一个特点,交易查询完之后,下游还有一个分析库处理,我们有一个密钥授权能力,在业务负责人将密钥权限授权下游处理节点后 ,数据库就把密文数据解密后托管给下游处理,这样后台数据就可以不经过客户端,不同的应用只需要使用同一个KMS(密钥管理)就可以操作同一部分数据。另外,只要业务负责人不把密钥授权给其他任何人,就没有人能处理这个数据,包括管理和运维人员。最后是获得的一些成绩,GaussDB是国内首个通过国际CC EAL4+认证的数据库,也是国内首批通过信通院全密态数据库评测、国内首家通过信通院防篡改数据库评测的数据库产品。今天的分享就到这里,欢迎小伙伴们一起交流。
-
本篇将分享GaussDB数据库迁移的创新实践。易迁移能力是企业数据库替换选型的关键考量 数据库的选型除了要看数据库本身的能力外,能否很平滑地从其他数据库迁移到GaussDB,也是很多企业考量的关键因素。而数据库能否平滑迁移有两个非常核心的要素,一个是数据库本身,比如能否很好地兼容主流数据库的语法,让应用少改或者不改;另外一个是在数据库外围能否提供一些好用、易用的迁移工具,把应用中内嵌的SQL、数据库中的对象以及全量和增量数据,在业务近乎零停机的情况下从其他数据库平滑地迁移过来。这两点是企业做数据库选型时考量的两个迁移关键要素。结构(UGO)+数据(DRS) 一站式迁移解决方案在2021年的DTCC大会上,发布了华为云结构+数据一站式迁移解决方案,其中有两个核心工具。一个工具是UGO,主要做结构和应用的语法兼容性评估和转换,比如将数据库上层应用中内嵌的SQL捕获出来进行评估,对数据库内部对象的DDL进行评估,并输出一个报告,清晰地展示哪些是数据库本身兼容的、哪些是通过UGO转换可以兼容的、哪些不能转换需要人工介入进行改造等。另外一个工具是DRS,大家都知道,异构数据库替换过程中的数据迁移问题非常非常多,DRS要解决的就是怎么在业务近乎不停机的情况下快速把客户的存量数据和增量数据迁移过来,并保证数据在任何情况下不丢、不错、不乱,同时提供灵活、多样的数据比对和修复能力。UGO+DRS一体化解决方案 在实际项目中得到验证UGO+DRS一站式迁移解决方案近两年在很多项目中都得到了验证和应用,这里举几个实际的例子。第一个是我们公司自己内部的MetaERP项目,使用UGO自动转换了近7亿行的O数据库SQL脚本,转换成功率接近100%,同时GaussDB实现了并行逻辑解码,性能高达近300MB/秒,可以让DRS轻松应对MetaERP在月结、季结和年结时10~20倍的流量洪峰,保证数据同步<5s的低时延。第二个是某银行的数据库替换,这个项目迁移复杂度比较高,面临应用多、数据库对象多、存储过程和package深度依赖等困难,截至目前通过我们的一站式迁移解决方案,完成了近1.3亿行SQL脚本(包含近8000万存储过程)的UGO自动转换,转换成功率超过96%,采用DRS迁移了近300套左右的O数据库实例,实现了O数据库与GaussDB数据库的长时间并机稳定运行,正反向低时延数据同步。项目实施过程中遇到新的困难与挑战 在大量的项目实施过程中,UGO+DRS一站式迁移解决方案也遇到了一些新的困难和挑战,这些挑战相信大家也都会遇到,在此给大家做个分享。挑战一在做异构数据库替换时,如何快速识别异构数据库语法不兼容点,识别数据相同的情况下相同SQL在不同数据库中执行的性能差异,以及低版本向高版本升级时是否会存在不兼容或性能劣化,再有就是如何模拟业务流量洪峰时的数据库行为表现。挑战二当前很多企业的开发人员和DBA对GaussDB熟悉程度还不高,SQL编写水平参差不齐,而且在做应用开发时缺乏统一的SQL编程规范和有效的SQL审核机制,很多烂SQL都流入了生产环境,进而引发大量的应用性能问题,影响生产业务和客户体验。挑战三很多数据库当前的字符集在标准字符集的基础上做了很多扩展或者定制,导致数据迁移时相同字符集的不兼容,或者就没有对等的字符集,更有甚者,历史数据里已经存在了各种各样的乱码数据,这些特殊场景都会影响迁移的平滑性。当然,困难和挑战还有很多,但这三个是会阻塞或拖慢数据库迁移进程的,那么针对这三个挑战,我们都做了哪些探索和创新呢?再给大家分享一下。应对挑战一:孵化数据库流量录制与回放能力流量录制与回放的概念相信大家都不陌生,在数据库领域,有些数据库厂商也提供了相应的工具,GaussDB面临的业务场景比较多,所以需要的技术也因场景而异。如果源数据库是公有云服务,而且提供了全量SQL,那么直接获取全量SQL并进行回放即可;如果源数据库开启了审计日志,也可以直接下载并解析审计日志,当然开启审计日志会对数据库的性能有一定的影响;如果源端是自建数据库,而且未开启审计日志,那就需要部署一个agent,通过捕获网络数据包,结合数据库本身的通信协议来解析出应用下发的所有SQL。基本上这三种方案可以涵盖所有的场景,这里面还要注意几个点,首先是要研究透不同数据库的通信协议,其次是实现异构数据库替换场景下的SQL自动转换,另外是要具备SQL回放的流量控制能力,能加速或者放慢等,当然在解析、回放等出现异常的情况下,要做好记录。接下来就是在源数据库的镜像库和GaussDB数据库同时进行流量回放,而且保证镜像库和目标数据库的数据完全一致,回放的SQL也完全一样,最终输出一个分析报告,比对每一条SQL的执行耗时、资源消耗、甚至是执行结果,很容易看出来哪些SQL的性能GaussDB比源数据库好、哪些出现了劣化、哪些是基本持平的。GaussDB团队正在和某银行进行数据库流量录制与回放的联合创新,从实际应用效果来看,通过agent方式捕获流量包,SQL抓取成功率可以做到97%以上,解析成功率和回放成功率可以达到95%,在此过程中,还可以识别到语法不兼容、语义不兼容的异常情况。应对挑战二:孵化GaussDB数据库SQL审核能力SQL审核大家更为熟悉,很多大的企业都会进行探索和实践,但对于GaussDB来说,由于是纯自主创新的分布式数据库,很多企业的开发人员和DBA还不熟悉GaussDB的SQL语法,也没有制定较为完善的SQL编程规范,很多第三方SQL审核工具也没有针对GaussDB的审核能力,这种情况下,我们结合UGO成熟的SQL解析器,以及多个项目中的SQL调优实践,孵化出了GaussDB数据库的SQL审核能力。SQL审核的输入可以有多种类型,可以是代码仓,也可以是一个SQL文件,还可以是通过流量录制获取的动态SQL等等,可以审核直接获取到的原生SQL,也可以审核通过UGO转换后的SQL。截至目前,已经沉淀了81条审核规则,并在公司内部的两个项目以及外部的多个银行进行了应用,效果超出预期。应对挑战三:孵化字符集兼容性分析评估能力针对数据迁移,大家最担心的莫过于正式割接时出现各种各样的问题导致割接失败,除了迁移工具本身的功能之外,最常见的可能就是字符集不兼容、数据乱码、生僻字等等。举个例子,O数据库对GBK字符集做了扩充,可以存储UTF-8字符,而GaussDB数据库的GBK字符集非常规范,从O数据库向GaussDB迁移数据时,这些UTF-8字符根本无法写入,迁移必然失败。更有甚者,很多客户的海量历史数据中有大量的乱码数据,无法确定这些数据是什么时候写入的,哪些应用写入的,或者后续会不会再用到,但客户要求必须迁移过来。那么,面对这些挑战,我们尝试通过孵化字符集兼容性分析评估工具来提前识别。这个工具的原理很简单,首先是建立一个可以分析的字符集基线,比如GB系、Unicode系列等,其次是获取源数据库的元数据,包括字符集、索引信息、表结构信息(列类型、列长度)等,然后基于源数据库和目标数据库的字符集做好映射,最后再对数据库进行数据扫描和分析,输出多维度的分析评估报告。目前这个工具正在和某银行进行联创,从前期的试用效果来看,确实能发现很多问题,比如ZHS16GBK和AL32UTF8两种字符集混编、直接写入二进制格式导致数据乱码、ZHS16GBK字符集使用了大量生僻字等。对UGO+DRS一站式迁移解决方案 的演进思考 以上是在使用UGO+DRS一站式迁移解决方案过程中遇到的三个大的挑战,以及应对这三个挑战做的一些创新实践。现在GaussDB的迁移场景越来越多,也越来越复杂,所以会不断地进行探索和创新,让方案更完善,迁移过程更平滑,比如流量回放、SQL审核、字符集兼容性评估会支持更多的数据库,推出非常详细和全面的应用、结构、数据迁移可行性分析报告,实现SQL捕获、转换、审核、优化全流程一体化管理等等,也希望能和客户、伙伴以及各位同行进行合作。以上是GaussDB数据库在迁移方面的一些创新实践,谢谢大家,欢迎交流。
-
数据库支持数据闪回技术概览简介数据闪回技术是一种数据库恢复机制,它允许数据库管理员(DBA)将数据库或其中的数据恢复到过去的某个时间点,以纠正由于误操作、错误数据或系统故障引起的问题。这项技术在多种数据库系统中都有所应用,包括但不限于Oracle、MySQL、PostgreSQL等。接下来,我们将详细探讨不同数据库系统中的数据闪回技术。Oracle数据库的闪回技术Oracle数据库提供了多种闪回技术,包括闪回查询、闪回表、闪回数据库等。这些技术基于数据库的日志文件(Undo日志)来实现数据还原。日志文件记录了数据库每次操作的详细信息,包括数据修改、事务提交等。通过解析日志文件,Oracle数据库可以将数据库还原到特定的时间点或操作前的状态。闪回查询闪回查询(Flashback Query)允许用户查询过去某个时间点的数据,而无需恢复整个数据库。用户可以通过指定时间点或系统更改号(SCN)来查询特定时间点的数据状态。闪回表闪回表(Flashback Table)可以将表恢复到过去某个时间点或SCN值时的状态。这项技术主要用于恢复指定表中的数据,而不影响数据库的其他部分。闪回数据库闪回数据库(Flashback Database)可以将整个数据库恢复到过去的某个时间点或SCN值。执行闪回数据库操作需要数据库启用归档日志模式,并有足够的磁盘空间来存储日志文件。MySQL数据库的闪回技术MySQL数据库原生不支持闪回功能,但可以通过第三方工具或自行编写脚本来实现类似的效果。例如,可以使用binlog来生成恢复SQL,进而实现数据的闪回恢复。第三方工具有开发者自行实现了MySQL数据库的闪回功能,如mysqlbinlog_flashback和binlog2sql等工具,这些工具可以解析binlog日志并生成用于数据恢复的SQL语句。PostgreSQL数据库的闪回技术PostgreSQL数据库提供了类似的闪回功能,包括闪回查询和闪回数据归档。它允许用户查询过去的数据版本,并在必要时执行数据恢复。闪回数据归档PostgreSQL的闪回数据归档(Flashback Data Archive)功能可以保留数据的历史版本,允许用户恢复到任意时间点的数据状态。总结数据闪回技术在不同数据库系统中的实现各有特色,但其核心目的是相似的:提供一种高效、可靠的数据恢复机制,以应对日常运维中不可避免的数据错误和损失。通过合理运用这些技术,DBA们能够在关键时刻保护企业的数据资产,确保业务的连续性和数据的完整性。
-
GaussDB(DWS)与GaussDB分布式版的区别概述GaussDB(DWS)和GaussDB分布式版都是华为推出的数据库产品,但在功能、架构和使用场景上存在一些差异。GaussDB(DWS)是一个云原生的数据仓库解决方案,而GaussDB分布式版则是指GaussDB的分布式部署形态。接下来我们将详细探讨这两个产品的区别。GaussDB(DWS)GaussDB(DWS)是华为云提供的云原生数据仓库服务,它采用全对称分布式架构,没有中心节点,所有节点都可以提供服务,实现千万条/秒入库吞吐,毫秒级入库时延,兼顾吞吐和时延要求。DWS具有高性能、高扩展、高可靠等特点,能够用一套软件替换多个数据组件,简化数据链路,统一运维,提供一站式数据分析解决方案。关键特性Serverless模式:支持按需资源,按需查询等灵活计费。存算分离:实现冷热数据自动管理,降低存储成本。数据格式兼容性:兼容Hudi/ORC/Parquet等开源数据格式,实现格式化和非格式化数据统一分析。表级细粒度容灾:按需创建容灾规模,最大化降低容灾集群投资。GaussDB分布式版GaussDB分布式版则是GaussDB的分布式部署形态,适用于可靠性、稳定性要求较高,实例规模较大的场景。分布式形态能够支撑较大的数据量,且提供了横向扩展的能力,可以通过扩容的方式提高实例的数据容量和并发能力。部署形态独立部署:数据库组件部署在不同节点上。高可用:采用一主两备或多活部署模式,提供高可用性。三副本:采用单节点的部署模式,包含一个控制节点和一个数据节点组件。性能优化智能查询优化技术:自动分析查询语句,选择最优的执行计划,提高查询效率。多种计算引擎:支持向量化执行引擎、列式存储引擎等,根据不同的应用场景选择最合适的计算引擎,实现更高效的数据处理。总结GaussDB(DWS)和GaussDB分布式版的主要区别在于它们的部署形态和所针对的使用场景。GaussDB(DWS)侧重于云原生环境和大规模数据分析,而GaussDB分布式版则更适合需要高可靠性和稳定性的企业级应用。两者都提供了高性能的数据处理能力,但GaussDB(DWS)在云服务和弹性扩展方面更具优势,而GaussDB分布式版则在独立部署和数据一致性方面更加突出。用户应根据自己的业务需求和技术背景选择合适的产品形态。
-
GaussDB数据库分页查询方式简介GaussDB数据库作为一款高性能的数据库产品,其分页查询能力是其核心功能之一。在处理大量数据时,分页查询可以帮助用户有效地检索和展示数据。本文将详细探讨GaussDB数据库中分页查询的具体实现方法和相关优化技巧。GaussDB分页查询的基本实现在GaussDB数据库中,分页查询通常涉及到LIMIT和OFFSET这两个关键词。基本的分页查询语句格式如下:SELECT * FROM table_name LIMIT offset, count;其中,offset参数指定了从哪一行开始查询,count参数指定了要查询的行数。例如,要查询从第11行开始的5行数据,则语句应为:SELECT * FROM table_name LIMIT 10, 5;这种方式在处理小规模数据时表现良好,但随着数据量的增大,性能可能会受到影响,特别是在没有合适的索引情况下。分页查询的性能优化为了提高分页查询的性能,可以考虑以下几个方面的优化措施:索引优化确保查询涉及的列上有适当的索引。例如,如果查询需要按某列排序,则应在该列上创建索引。这样可以减少数据库的排序开销,加快查询速度。子查询优化在某些情况下,可以使用子查询来优化分页查询。例如,可以先找出最后一页的最大ID,然后在下一页的查询中使用这个ID作为起始点,从而避免每次都从头开始扫描。窗口函数优化GaussDB支持窗口函数,如ROW_NUMBER(),可以在查询中使用它来计算每行的序号,进而进行分页。这种方法在Oracle数据库中被称为ROWNUM,但在GaussDB中使用窗口函数可以获得更好的性能。避免全表扫描尽量避免全表扫描,特别是在数据量很大的情况下。可以通过在WHERE子句中添加过滤条件,并结合索引使用,以减少扫描的数据量。总结GaussDB数据库提供了多种分页查询的方式,并通过优化技术提高了查询性能。在实际应用中,应结合具体场景选择最合适的方法,并根据数据量和查询特点进行相应的性能调整。通过合理的索引设计和查询优化,可以确保分页查询在面对大规模数据时仍能保持高效。
-
GaussDB、DWS、GaussDB A、GaussDB T、openGauss概念理解GaussDB数据库概述GaussDB是华为自主研发的关系型数据库,它支持x86和鲲鹏处理器,提供高并发事务实时处理能力、两地三中心金融级高可用能力和分布式高扩展能力。GaussDB数据库适用于金融、政府、电信、大企业等行业核心关键系统。GaussDB T数据库是GaussDB系列中的一员,专注于事务处理,而GaussDB A数据库则具备分析及混合负载能力,适合数据仓库、数据集市、实时分析等场景。GaussDB T数据库特性GaussDB T数据库特别适合于需要处理大量事务的系统,例如电信计费、银行交易等。它支持ACID事务、MVCC多版本并发控制,确保数据的一致性和完整性。GaussDB T数据库在基于鲲鹏处理器的16节点TPC-C标准测试中,性能达到千万级tpmC,显示出其在高并发场景下的优秀性能。GaussDB A数据库特性GaussDB A数据库支持行存储与列存储,提供PB级数据分析能力、多模分析处理能力。它适用于数据仓库、数据集市、实时分析、实时决策和混合负载等场景,广泛应用于金融、政府、电信、大企业等行业核心系统。GaussDB A数据库基于鲲鹏920处理器,相对通用同期芯片,TPC-H/TPC-DS性能提升30%。openGauss数据库概述openGauss是华为开源的数据库项目,旨在打造一个高性能、可伸缩、安全的开源数据库。openGauss社区聚集了众多企业和开发者,致力于推动数据库技术的创新和发展。openGauss社区已经有290多家企业和机构加入,近5000名开发者参与社区贡献,下载量突破190万次。GaussDB与openGauss的关系GaussDB和openGauss有着紧密的联系。GaussDB是华为基于openGauss开源社区的基础上开发的闭源数据库产品。两者共享相同的开源根源,但GaussDB作为闭源产品,提供商业级别的支持和担保,而openGauss则作为一个开放社区,鼓励开发者参与贡献,共同推动数据库技术的发展。总结综上所述,GaussDB、GaussDB T、GaussDB A和openGauss构成了华为在数据库领域的产品和项目矩阵。GaussDB系列数据库针对不同的应用场景提供了特定的优化和功能,而openGauss则作为一个活跃的开源社区,促进了数据库技术的普及和创新。通过这样的组合,华为不仅为行业客户提供了多样化的数据库产品选择,也为全球开发者提供了一个共建共享的开源平台。
-
GaussDB支持场景● 通常全量物化视图所支持的查询范围与CREATE TABLE AS语句一致。● 全量物化视图上支持创建索引。● 支持analyze、explain不支持场景物化视图不支持增删改操作,只支持查询语句。约束全量物化视图的刷新、删除过程中会给基表加高级别锁,若物化视图的定义涉及多张表,需要注意业务逻辑,避免死锁产生。
-
GaussDB概述全量物化视图仅支持对已创建的物化视图进行全量更新,而不支持进行增量更新。创建全量物化视图语法和CREATE TABLE AS语法类似。使用语法格式● 创建全量物化视图CREATE MATERIALIZED VIEW [ view_name ] AS { query_block };● 刷新全量物化视图REFRESH MATERIALIZED VIEW [ view_name ];● 删除物化视图DROP MATERIALIZED VIEW [ view_name ];● 查询物化视图SELECT * FROM [ view_name ];示例--准备数据。gaussdb=# CREATE TABLE t1(c1 int, c2 int);gaussdb=# INSERT INTO t1 VALUES(1, 1);gaussdb=# INSERT INTO t1 VALUES(2, 2);--创建全量物化视图。gaussdb=# CREATE MATERIALIZED VIEW mv AS select count(*) from t1;CREATE MATERIALIZED VIEW 1--查询物化视图结果。gaussdb=# SELECT * FROM mv; count------- 2(1 row)--向物化视图中基表插入数据。gaussdb=# INSERT INTO t1 VALUES(3, 3);INSERT 0 1--对全量物化视图做全量刷新。gaussdb=# REFRESH MATERIALIZED VIEW mv;REFRESH MATERIALIZED VIEW--查询物化视图结果。gaussdb=# SELECT * FROM mv; count-------3(1 row)--删除物化视图。gaussdb=# DROP MATERIALIZED VIEW mv;DROP MATERIALIZED VIEW
-
书接上文GaussDB关键技术原理:高弹性(四)从扩容流程框架方面对hashbucket扩容技术进行了解读,本篇将从日志多流和事务相关方面继续介绍GaussDB高弹性技术。4.2 日志多流本节介绍日志多流技术,hashbucket扩容的思路仍然是基线数据加增量数据,其中基线数据为bucket物理文件和bucket级CLOG文件,增量数据采用搬迁增量XLOG并回放日志的方式进行追增。日志多流只在hashbucket扩容期间动态的产生和使用,扩容框架会根据当前正在搬迁的bucket列表,解析并生成对应的日志流用来进行后续的数据追增。4.2.1 日志多流总体流程日志多流总体流程由gs_redis_bucket工具下发的MOVE BUCKETS语句触发,ALTER DATABASE database_name MOVE BUCKETS (bucket_list) FROM sender_dn TO receiver_dn;MOVE BUCKETS语句中包含如下信息:正在进行扩容重分布的库database_name,本批搬迁bucket列表的bucketlist,老节点为sender_dn,新节点receiver_dn。如图所示为日志多流示意图。主要涉及三个角色:老节点主DN(下简称老DN),新节点主DN(简称新DN),新节点备DN(简称备DN)。CN收到MOVE BUCKETS命令后转发给老DN和新DN。图1 日志多流示意图新DN收到MOVE BUCKETS命令后启动receiver线程,receiver线程负责与其他节点进行数据传输。receiver线程与老DN建立连接,老DN启动sender线程;receiver与备DN建立连接,备DN启动standby线程。sender、standby线程也负责与其他节点进行数据传输。建连后,receiver向sender发送BUCKETBASE请求,sender将对应于bucketlist的基线数据(包括bucket数据文件、CLOG文件等)发送给receiver。receiver再将基线数据转发给standby。另一方面,老DN收到MOVE BUCKETS命令后启动parser线程,将bucketlist对应的增量XLOG日志筛选出来放在bucketxlog目录下。待基线数据传输完成后,sender将增量XLOG日志发送给receiver,receiver转发给standby。日志传输完成后,新DN和备DN拉起startup线程,进入日志回放逻辑,通过回放增量xlog日志的方式,追加增量数据。因此,追增完成的判断分为两部分,一部分是parser解析到老DNbucketlist对应的最新LSN,另一部分新DN和备DN回放完所有存量bucketxlog。4.2.2 基线数据传输sender收到receiver的BUCKETBASE请求后向receiver传输基线数据。按照tablespaceoid map、bucket数据文件、CLOG文件的顺序进行传输。若包含备机,基线数据部分都需要传输到备机。tablespaceoid map包含sender节点上tablespace的name与oid的对应关系。由于sender和receiver分别在不同的DN上,同一个tablespace在不同DN上的tablespaceid可能是不同值,因此在日志回放前需要将日志中的tablespaceid及dbid替换成本地的tablespaceid及dbid。receiver根据name通过tablespaceoid map查到本地的tablespaceoid,在后续XLOG解析阶段进行替换。tablespaceid的映射关系需要传到备机。bucket数据文件是位于对应database的数据目录下形如 *_b* 的文件,如:/base/db_oid目录或/pg_tblspc/tblspc_oid/db_oid目录下的2_b1,2_b1.1,2_b1_fsm,2_b1_vm等。CLOG文件按bucket粒度拆分,在基线数据搬迁时,sender将对应bucket的所有CLOG文件均传输给receiver。CLOG搬迁涉及事务提交状态及可见性等问题,详见"事务相关" 小节。另外,在接收完成基线数据后,遍历有CBI索引的表,扫描对应bucket上的heap页面,插入索引作为基线数据,详见"CBI索引相关处理"小节。至此基线数据传输阶段完成,进入日志传输与回放阶段。4.2.3 日志传输与回放增量数据通过XLOG日志传输和日志回放的方式进行追增。首先sender节点的parser线程挑选出需要回放的日志并写入bucket_xlog目录。sender线程收到receiver的BUCKETXLOG请求后,从bucket_xlog目录读取日志传输给receiver。receiver节点的receiver线程将收到的XLOG日志转发给standby并写入bucket_xlog目录。最后startup线程启动回放工作线程进行回放。standby节点与receiver节点同理。4.2.3.1 日志流的处理(1)parser挑选bucketlist对应日志DML日志只涉及一个bucket,在发送和接收时只需要根据bucketlist过滤即可。而commit/abort日志则可能包含多个bucket,因此需要特殊处理:commit/abort日志只涉及一个bucket写日志时,则与DML日志一样,在header部分写入bucketid,在receiver回放时直接进行回放;commit/abort日志包含多个bucket,则在header部分写入一个特殊的id(ComboBktId),在receiver回放时,将无关的bucketid给过滤掉,只回放bucketlist中的bucketid。(2)日志格式修改将bucket日志从原来的XLOG中挑出来写到新的日志文件后,原来的LSN信息丢失了,这导致后面回放时LSN校验失败。为了保留原始的LSN值,在解析日志时将原始的LSN值写在bucket日志的后面,在回放前,用这个LSN值去替换日志的LSN。图2为日志格式修改示意图。图2 日志格式修改示意图(3)日志中元数据的处理日志多流技术中,新节点上的数据可能来自于不同的老节点,相同的tablespace及database在不同DN上对应的tablespaceid及dbid很可能是不同的,因此在日志回放前需要将日志中的tablespaceid及dbid替换成本地的tablespaceid及dbid。替换方法:dbid: 在进行重分布前,在内核中记录各个节点本次要重分布的dbid,在日志回放的解析日志阶段,把日志里所有的block里的dbid进行替换。tablespaceid: 由于tablespaceid可能会有多个,sender会把tablespace的name与id的对应关系传给receiver,receiver再根据name查出本地的tablespaceid,然后在解析阶段进行替换。tablespaceid的映射关系需要传到备机。4.2.3.2 回放的处理startup线程会拉起回放工作线程,包括pageredo线程、bucketwriter线程和bucketflush线程。同时使用私有缓冲区隔离,避免未上线前污染共有缓冲区。图3为日志回放示意图。图3 日志回放示意图pageredo线程负责日志回放,bucketwriter线程负责将私有缓冲区中的内容注册给bucketflush线程,bucketflush线程负责刷脏工作。同时新增共享变量,记录需要落盘的页面信息。bucketwriter线程负责把缓冲区中的所有内容记录到共享变量中,在后台轮询工作。bucketflush线程启动时会初始化本地hash表,bucketflush线程从共享变量中拷贝需要刷盘的信息到本地hash表中,完成落盘操作。以上所有操作均在startup线程存在期间完成,扩容上线逻辑会判断bucketwriter线程是否完成刷页,bucketwriter线程会等待bucketflush线程完成落盘,因此上线提交时能够保证所有页面已经完成落盘。如果此时发生故障,上线事务回滚,下次重入时本批bucket重新进行move bucket全逻辑,以保证数据正确性。4.2.4 CBI索引相关处理GaussDB针对hashbucket表有两种索引,bucket全局索引(跨bucket索引,cross-bucket index, CBI)和bucket本地索引(local-bucket index, LBI)。CBI索引为段页式存储,表现为只有一个bucketnode为1024的relation,索引元组中额外存储tablebucketid,从而缩小扫描范围;LBI索引为hashbucket类型的特殊段页式存储,同hashbucket表,pg_class中虽只有一条记录,存储层有bucketnode为[0-1023]的fake relation存在,索引扫描时需逐个遍历bucket索引。CBI索引比LBI索引少一层顺序遍历bucket的扫描,故查询性能显著提升。但由于CBI索引为段页式表,不会通过物理文件搬迁和bucket日志回放的方式进行重分布,故需对其进行特殊处理,思路仍然是基线数据+增量数据。图4为CBI索引基线数据构建与日志追增示意图。图4 CBI索引基线构建与追增示意图基线数据搬迁完后,启动cbi_insert_worker线程,使用私有缓冲区。遍历有CBI索引的表,扫描对应bucket上的heap页面,插入索引作为基线数据。全部CBI索引基线数据构建完成后,完成基线数据搬迁阶段,进入日志传输与回放阶段。CBI索引相关XLOG记录特殊bucketid,扩容时随日志流传输,作为扩容期间CBI增量数据的标记。启动回放线程时启动cbi_insert_worker线程解析CBI索引相关的记录了特殊bucketid的XLOG日志,提取数据后插入索引。4.3 事务相关4.3.1 CLOG拆分4.3.1.1 事务ID分配及CLOG/CSNLOG为了在数据库内部区别不同的写事务,GaussDB会为它们分配唯一的标识符,即事务id(transaction id,缩写xid),xid是uint64单调递增的序列,从FIRST_NORMAL_XACT_ID (3)开始分配。对于页面上的元组,xmin记录插入时的xid,xmax记录删除时的xid。当事务结束后,使用CLOG记录是否提交。对于每个xid,一共有4种状态:事务未开始或还在运行中、已经提交、已经回滚、子事务已经commit而父事务状态未知。可以用2个bit记录一个xid状态,所以8K的页面可以记录32K个xid状态。使用CSNLOG(commit sequence number log)记录该事务提交的序列,用于可见性判断。CSN是uint64单调递增的序列,从COMMITSEQNO_FIRST_NORMAL(3)开始分配。一个CSN占用8字节,所以一个8K的页面可以记录1K个xid状态。CSNLOG以及CLOG均采用了SLRU(simple least recently used,简单最近最少使用)机制来实现文件的读取及刷盘操作。4.3.1.2 CLOG拆分背景xid是由各个DN自己维护的。在hashbucket扩容中,不同源DN的CLOG可能会搬迁到同一个新DN。同一个xid在不同DN记录的提交状态可能不一样,无法用同一个CLOG去表示不同bucket的提交状态。例如DN1、DN2为源节点,DN3为新节点,扩容重分布过程中会把DN1和DN2中的CLOG日志搬到DN3。xid100的状态在DN1是已提交,在DN2是已回滚。因此,CLOG需要按bucket粒度拆分。拆分后的CLOG目录如下图5,路径为数据目录/pg_clog。子目录名1表示bucketid,文件名000000000000表示对应的CLOG段文件。对于非hashbucket表,每SLRU_PAGES_PER_SEGMENT(2048)个页面切分一个段文件,文件名长度为8;对于bucket子目录下的CLOG文件,每SLRU_CLOG_PAGES_PER_SEGMENT(4)个页面切分一个段文件,文件名长度为10。文件名长度不同是为了方便解析工具判断段文件最多可容纳的页面数。图5 CLOG磁盘目录4.3.1.3 CLOG拆分处理可见性判断图6 快照可见性判断流程图snapshot.xmin:获取快照时记录当前活跃的最小的xidsnapshot.snapshotcsn:当前最新提交的CSN号 + 1如上图6所示,xid对于当前快照是否可见的简化有步骤如下:(1) xid < snapshot.xmin,事务在快照开始前已经结束,根据CLOG状态判断是否提交:CLOG显示已提交,可见;否则,不可见。(2) xid≥snapshot.xmin,事务在快照开始前未结束,根据CSNLOG读取xid对应的CSN。(3) 如果CSN已提交,即CSN≥3,没有子事务标志,没有正在提交标志。如果CSN< snapshot.snapshotcsn,则可见,否则不可见。(4) 如果CSN正在提交,则等待事务结束,重入(3)判断。(5) 其他情况,不可见。图7 新节点快照可见性判断流程图图7为新节点快照可见性判断流程图。bucketxid:bucket粒度,在当前库,新节点产生的最小xidbucketcsn:bucket粒度,在当前库,来自源节点的最大CSNbucket上线后,CLOG和数据文件已搬迁,CSNLOG未搬迁。CLOG拆分后对可见性判断:老快照判断迁移数据的可见性:报错。因为CSNLOG未搬迁,无法读取CSN号;老快照判断新数据的可见性:元组是在bucket上线后插入的,即tuple.xmin > bucketxid。不可见;新快照判断迁移数据的可见性:通过CLOG;新快照判断新数据的可见性:正常可见性判断逻辑;4.3.2 xid调整4.3.2.1 xid调整背景图8 源节点、新节点xid范围示意图如上图8所示,新节点的每个bucket粒度的xid可以看成两段。左边一段是从源节点迁移过来的,也就是搬迁的CLOG中记录的。它的最大值next_xid是源节点下一个写事务分配的xid,最小值是最小活跃xid , 是源节点当前最小的需要通过CLOG读取事务状态的xid。Vaccum操作会清理掉页面中小于最小活跃xid的值,如果事务提交,则改为FROZEN_XACT_ID(2),表示对所有快照可见。如果事务回滚,则清理掉对应元组。右边一段是新节点业务生成的,最小的xid是bucket在第一个库的上线事务对应的id,记为bucketxid。这个值可以在pg_hashbucket系统表的bucketxid列获取。如果不调整xid, 那么新节点业务生成的xid和从源节搬迁过来的xid就有重合的问题,导致可见性判断错误。例如DN1为源节点,DN2为新节点。重分布前,bucket1的xid100的状态在DN1是已提交。DN2的xid没有调整,是从3开始分配的。bucket1在DN2上线后,使用xid100,并且状态为已回滚。那么在DN2读取迁移数据中的xid100提交状态错误。4.3.2.2 xid调整流程在加节点过程中,会调整新节点下一个要分配的xid,图9为xid调整流程图。图9 xid调整流程图根据源节点下一个要分配的xid(对应图中的next_xid)和业务对xid的消耗量计算新节点的预期xid计算exp_xid。计算下一步调整到的xid为next_step_xid = min(exp_xid, 新节点next_xid + 10亿)。这里需要分步调整xid。页面的xid取值范围依赖当前的最小活跃xid。如果一次设置为预期值,最小活跃事务号没有办法及时更新,则新设置的xid可能会超过已有页面的xid合法表达范围,出现写业务报错。如果新节点next_xid < exp_xid,设置新节点next_xid为next_step_xid,并等待当前活跃事务的最小值推进,更新next_step_xid,直到next_xid不小于预期值。4.3.3 bucket锁类似于常规锁的表锁,对于hashbucket表,物理文件是库级bucket化的,扩容过程也是按照bucket级别上线的,因此引入一种新型的锁——bucket锁,每个bucket对应一把锁。只有用户业务的场景,DML和DDL业务间的并发仍然通过表锁实现,所有业务都拿bucket的一级锁。当用户扩容时,此时会发生bucket文件的搬迁,同时实现元数据从老节点下线,新节点上线的动作,此时需要通过bucket锁对用户业务做互斥。因此,bucket锁主要用在hashbucket在线扩容期间bucket在新节点上线时和在线业务做互斥,保证业务数据正确。新增如下的语法来实现这一功能:LOCK BUCKETS(bucketlist) IN LOCK_MODE [CANCELABLE];其中,bucketlist如0,1,2,3表示次轮上线的bucket桶号,取值范围0-1023;LOCK_MODE只有两种级别:ACCESS SHARE MODE和ACCESS EXCLUSIVE MODE增加可选项[CANCELABLE]表示是否通过cancel用户业务而保证扩容拿到锁。在线业务和扩容的交互如下图10所示:图10 xid调整流程图t1时刻:对bucket 0操作的DML在上线事务之前的拿锁成功,数据重分布上线事务拿bucket 0的8级锁处于等待状态,排在数据重分布上线事务之后其它线程对于bucket 0的访问等在上线事务的8级锁上。t2时刻:排在上线事务之前的用户业务放锁,上线事务持8级锁成功,之后所有访问bucket 0的用户业务均阻塞。t3时刻:bucket 0在老节点下线,新节点上线,用户业务拿到bucket 0的锁获取最新的数据分布方式。如果CN上能确定当前操作的bucket,则在CN上拿对应bucket的1级锁,如果不能确定则在DN上拿锁,通过前文提到过的pg_hashbucket记录的bucketlist进行过滤。扩容上线的LOCK BUCKETS语句现在执行CN拿锁成功再发送到其它所有CN和DN拿锁,全部成功则成功。以上内容从hashbucket扩容方面对GaussDB高弹性能力进行了解读,下篇将从扩容实践方面继续介绍GaussDB高弹性技术,敬请期待!
上滑加载中
推荐直播
-
华为云码道 × 仓颉编程:工程化AI编码探索2026/05/27 周三 19:00-21:00
刘俊杰-华为云仓颉语言专家/李炎-华为云码道技术专家/王智鹏-OpenCangjie开源社区发起人
本场直播围绕华为云仓颉语言与华为云码道的深度结合,展示华为云智能编程从零基础到高效落地的完整生态能力。以华为云码道为引擎,仓颉语言为载体,带给大家日常提效、趣味创新到极速量产的开发体验。
回顾中
热门标签