• [其他问题] 【GaussDB】库中表大小估算及占用磁盘空间的问题
    【GaussDB数据库】关于gs_class系统表的relpages与reltuples字段,表中数据实际占用空间大小【操作步骤&问题现象】1、pg_class中relpages、reltuples两个字段的记录如何进行数据换算得到表大小?(如relpages是否是乘以blcksz就可以得到表大小)2、pg_table_size函数得到的表大小是否是实际磁盘占用空间?3、表占用的实际磁盘空间是否为表本身大小的两倍?(主从机制的备份需要)【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [生态空间] 【GaussDB】pg_class系统表中relpages与reltuples 如何用于估算表大小
    【GaussDB数据库】关于gs_class系统表的relpages与reltuples字段【操作步骤&问题现象】1、pg_class中relpages、reltuples两个字段的记录如何进行数据换算得到表大小(如relpages是否是乘以blcksz就可以得到表大小)2、pg_table_size函数得到的表大小是否是实际磁盘占用空间3、表占用的实际磁盘空间是否为表本身大小的两倍?(主从机制的备份需要) 【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [生态空间] 【GaussDB】pg_class系统表中relpages与reltuples 如何用于估算表大小
    【GaussDB数据库】关于gs_class系统表的relpages与reltuples字段【操作步骤&问题现象】1、pg_class中relpages、reltuples两个字段的记录如何进行数据换算得到表大小(如relpages是否是乘以blcksz就可以得到表大小)2、pg_table_size函数得到的表大小是否是实际磁盘占用空间【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [POC&交付] GaussDB DWS中的内存资源配置实践
    GaussDB提供了资源负载管理手段,来均衡任务对系统资源的利用。资源负载管理实现如下功能:通过创建并管理租户,实现按租户进行系统资源(CPU、内存、IO、存储空间)的隔离和作业的异常处理。通过限制集群和资源池允许运行的并发量,超出并发量的作业进行排队,以保证重点业务的运行,防止并发过多导致的性能下降。通过优先级控制实现对资源的有效调度,高优先级的作业得以优先执行。支持多维度的资源监控视图,可以查看作业的实时资源记录和历史资源记录。相关概念资源管理GaussDB DWS对于系统资源的管理范围包含CPU资源、内存资源、IO资源和存储资源。通过对系统的资源进行合理的分配,避免发生资源的不合理占用导致系统运行效率下降或者引发系统运行问题。负载管理GaussDB DWS通过对业务的并发控制,实现系统负载的均衡。避免业务间争抢资源,实现所有作业的和谐共处,达到资源利用最优。控制组控制组(Cgroups)是control groups的缩写,是Linux内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如:CPU、内存、IO等)的机制。如果一个进程加入了某一个控制组,该控制组对Linux的系统资源都有严格的限制,进程在使用这些资源时,不能超过其最大限制。更多Cgroups的原理介绍,请查看相关操作系统的产品手册。资源池资源池(Resource Pool)是GaussDB提供的一种配置机制,用于对主机资源(内存、IO)进行划分并提供SQL的并发控制能力。资源池通过绑定Cgroups对资源进行管理。用户通过绑定资源池可以实现对其下作业的资源负载管理。本文简单介绍GaussDB内存资源管理的配置部分。内存是GaussDB 运行的一个关键资源,如果能够有效利用,可以提升业务查询性能。内存管理分为如下三个类型:实例级别的内存管理通过设置系统级别的GUC参数“max_process_memory”,可以对数据库实例的最大可用物理内存进行管理。当作业申请的内存超过了给定限制时,会因为内存申请失败触发异常处理。根据实例在执行业务时的不同分工,需要的内存大小也不同。资源池级别的内存管理通过设置资源池的参数“MEM_PERCENT”,可以对资源池的内存进行管理。作业级别的内存管理通过设置session级别的GUC参数“query_mem”,可以对作业可用内存进行管理。对内存资源管理进行配置的前提条件是逻辑内存管理功能已经开启,即参数enable_memory_limit已设置为“on”。如果此参数为“off”,则通过gs_guc set -Z coordinator -Z datanode -N all -I all -c "enable_memory_limit=on"来开启逻辑内存管理功能。参数描述如下:-N all:表示集群所有主机。-I all:表示实例主机中所有的实例。enable_memory_limit:为逻辑内存管理模块的开关。coordinator/datanode:表示执行该配置的实例类型为CN/DN实例。通过下列步骤可以配置数据库实例级的内存管理:1、设置数据库DN实例的最大可用内存。max_process_memory为实例的最大可用内存,datanode表示执行该配置的实例类型为DN实例。      gs_guc set -Z datanode -N all -I all -c "max_process_memory=32GB"2、设置数据库CN实例的最大可用内存。根据经验,推荐将CN的最大可用内存设置为与DN一致,coordinator表示执行该配置的实例类型为CN实例。      gs_guc set -Z coordinator -N all -I all -c "max_process_memory=32GB"3、重启集群并执行作业。     gs_om -t stop && gs_om -t start通过下列步骤可以配置资源池级别的内存管理:修改资源池“resource_pool_a1”的内存比例为可用内存大小的20%,即设置MEM_PERCEN的取值为20。多租户场景下:MEM_PERCENT的取值设置为"x"(1<=x<=100),表示设置资源池使用的内存大小为可用内存大小的"x%",查询作业将使用给定的内存来运行。非多租户场景下:当MEM_PERCENT参数取值为0时,查询作业的内存不受限。当MEM_PERCENT参数取值为"x"(1<=x<=100)时,表示设置资源池使用的内存大小为可用内存大小的"x%",查询作业将使用给定的内存来运行。ACTIVE_STATEMENTS取值范围为 -1 ~ INT_MAX, 默认值为10,建议使用该默认值。当设置为0或者-1时,内存不受限制。通过下列步骤可以配置作业级的内存管理:1、设置query_mem为500MB     set query_mem='500MB';2、当结果显示为如下信息,则表示设置成功。     SET3、执行作业。     如果query_mem超过资源池可用内存的上限或者低于256MB时,query_mem将不起作用,作业依然使用work_mem。查看内存资源的配置信息           查询实例级别的内存设置show max_process_memory;查看资源池级别的内存设置select * from pg_resource_pool;查看作业级别的内存设置show query_mem;内存监控         查看当前CN的内存使用情况。        SELECT * FROM pg_total_memory_detail;               查询整个集群的内存使用情况        通过视图pgxc_total_memory_detail查询,必须具有sysadmin权限。        
  • [技术干货] 2021HDC.Cloud|华为云GaussDB(DWS)首席架构师解读一站式数据分析能力
    4月26日,在华为开发者大会(Cloud)上,华为云数据使能DAYU主力产品GaussDB(DWS)首席架构师解读了GaussDB(DWS)的一站式数据分析能力。随着大数据观念逐步深入,数据分析带来的价值愈发被大家重视起来。从PC时代,到互联网时代、移动互联网时代,数据应用不再是简单的分析和挖掘,而是更加智能化。典型企业分析场景主要分为实时分析处理,批量分析处理以及交互式查询处理。当前常见的解决方案用不同技术解决不同问题:使用Hana,Oracle Exadata处理实时分析场景;使用Teradata,Greenplum处理批量分析场景;使用Oracle和SQL Server等处理交互式查询场景。从单一场景来看都是不错的选择,但是站在整体数据域视角去看,这种搭积木式的方案带来诸多问题 ,例如组件多,开发方式不统一,数据格式不统一,反复转换消耗算力和存储空间;组件间的数据流转开发复杂,流转效率低;跨集群,跨组件数据一致性差等。华为云GaussDB(DWS)从两个维度构筑能力,为企业用户提供一站式分析能力:在全并行分布式架构上,无缝融合时序引擎、OLAP引擎、CEP引擎,同时支撑实时分析、批量分析和交互式查询等不同业务负载,达到开发统一、部署统一、维护统一、数据格式统一,真正做到一个产品包办的一站式分析;异构平台数据融合、协同分析,构筑全域数据一体化。当前企业IT系统不会是白纸一张,在不同阶段曾经采用不同技术建设的多套系统承载着不同的业务,这些系统还未完成历史使命,将延续使用相当长一段时间。华为云GaussDB(DWS)支持多样性的数据融合分析能力,无缝融合并协同分析企业现有平台数据,让老IT系统产生的数据焕发新价值。一、T+0实时分析业务场景中实时数据源种类繁多,针对不同数据源采用不同实时处理技术。时序引擎支持时序数据分析,内置100多种时序分析算法,将时序数据接入后实时合并;流引擎接入基于Kafka/Flink等流组件产生的流式数据,支持对流数据自定义持续计算。二、全并行批量分析基于Share-nothing分布式架构,华为云Gauss DB(DWS)天然具备大规模的分布式并行处理能力。多层级并行技术将系统性能推至极致,包括节点间并行、节点内SMP并行,CPU指令级并行以及动态编译技术。同时,通过自研TCP多流、多线程包合并、通信代理等技术,将scale-out能力推至极致,华为云GaussDB(DWS)也是目前唯一通过信通院2048节点大集群权威认证的分布式数据库产品。三、多场景交互式查询对短查询做了全流程梳理,从接入、SQL解析、计划发送、执行和数据扫描进行了一系列优化;由于Ad-hoc查询的负载具有不可预见性,经常可能会出现单一查询拖慢甚至拖垮整个集群的情况,华为云GaussDB(DWS)内置动态智能负载管理组件,实时监控运行状态和资源消耗,对异常作业自动预警并智能干预,例如内存占用过高,运行时间过长,大量数据广播等异常情况,系统会自动查杀等。以银行业务为例,“手机银行用户实时数据查询”与“网银系统交易流水批量作业”是最常见的业务场景,采用2套技术方案或2个平台分别处理,则会出现资源重复投入。使用华为云GaussDB(DWS)实现2个业务场景需求,数据无需反复转换和流转,提升了业务处理效率,节省运维成本。2小时可完成7万个核心业务的银行日增量数据归档和数据加工,同时支持手机银行终端7x24小时实时查询;当上千万个人用户与几十万企业用户同时使用系统,并发进行日间批量作业10万个的批量高峰期,实时查询可在3秒内响应,真正做到跑批和实时作业互不影响。华为云GaussDB(DWS) 面向未来,构筑新一代、全场景、云数据仓库,一站式数据分析,释放非凡数据价值,做企业数字化转型的最佳伙伴。
  • [其他] DWS集群之BMS裸金属磁盘RAID配置
    配置方法:1.serviceOM--》裸金属资源--》BMC IP地址--》BMC地址2.iBMC登录后--》存储--》存储管理--》“添加”--》配置完成后保存
  • [其他] DWS如何kill实例
    DWS如何kill实例?方法如下:1. 找到需要kill的实例例如,需要kill dn_6020实例,查看集群状态找到该实例的节点host和实例目录:2. ssh连接到对应节点3. 根据第一步查到的实例目录,找到对应的pid,kill实例实例kill完后,会被cma重新拉起,重新ps -ef | grep 查看进程号是否变化,发生变化说明kill 成功
  • [产品介绍] 【DRS云小课】如何通过DRS实现他云MySQL到GaussDB(for MySQL)的数据迁移
    数据复制服务(DRS)是一种易用、稳定、高效、用于数据同步的云服务,本节小课为您介绍,如何通过DRS将其他云 MySQL实例的数据迁移到华为云GaussDB(for MySQL)。使用场景DRS实时迁移可自动化迁存量数据并持续同步增量数据,保证源和目标数据近实时一致,可自由选择业务割接窗口实现平滑无感搬家,可迁表、视图、存储过程、触发器、用户权限、参数等特性。本实践中的选择均为测试简化基本操作,仅做参考,实际情况请用户按业务场景选择,更多关于DRS的使用场景请单击这里了解。部署架构本示例中,DRS源数据库为其他云MySQL,目标端为华为云云数据库GaussDB(for MySQL),通过公网网络,将源数据库迁移到目标端。创建GaussDB(for MySQL)实例1. 登录华为云控制台。2. 单击管理控制台左上角的,选择区域“华南-广州”。3. 单击左侧的服务列表图标,选择“数据库 > 云数据库 GaussDB”。4. 选择GaussDB(for MySQL),单击“购买数据库实例”。5. 配置实例名称和实例基本信息。6. 选择实例规格。7. 选择实例所属的VPC和安全组、配置数据库端口。VPC和安全组已在创建VPC和安全组中准备好。8. 配置实例密码。9. 单击“立即购买”。10. 返回云数据库GaussDB实例列表。当GaussDB(for MySQL)实例运行状态为“正常”时,表示实例创建完成。其他云MySQL实例准备前提条件已购买其他云数据库MySQL实例。帐号权限符合要求,具体见帐号权限要求。帐号权限要求当使用DRS将其他云MySQL数据库的数据迁移到华为云云数据库GaussDB(for MySQL)实例时,在不同迁移类型的情况下,对源数据库的帐号权限要求如下:迁移类型全量迁移全量+增量迁移源数据库(MySQL)SELECT、SHOW VIEW、EVENT。SELECT、SHOW VIEW、EVENT、LOCK TABLES、REPLICATION SLAVE、REPLICATION CLIENT。MySQL的相关授权操作可参考操作指导。网络设置源数据库MySQL实例需要开放外网域名的访问。各厂商云数据库对应方法不同,请参考各厂商云数据库官方文档进行操作。以阿里云RDS MySQL为例,需要通过申请外网地址来允许外部的应用对接,具体的操作及注意事项可以参考其官方文档进行操作他云提供的相关指导。创建DRS迁移任务本章节介绍如何创建DRS实例,将其他云MySQL上的数据库迁移到华为云GaussDB(for MySQL)。迁移前检查在创建任务前,需要针对迁移条件进行手工自检,以确保您的同步任务更加顺畅。本示例为MySQL到GaussDB(for MySQL)入云迁移,您可以参考入云迁移使用须知获取相关信息。创建迁移任务1. 登录华为云控制台。2. 单击管理控制台左上角的,选择区域,本示例中为“华北-北京四”。3. 单击左侧的服务列表图标,选择“数据库 > 数据复制服务 DRS”。4. 单击“创建迁移任务”。5. 填写迁移任务参数:配置迁移任务名称。填写迁移数据并选择模板库。这里的目标库选择创建GaussDB(for MySQL)实例所创建的GaussDB(for MySQL)实例。6. 单击“下一步”。迁移实例创建中,大约需要5-10分钟。7. 配置源库网络白名单。源数据库MySQL实例需要将DRS迁移实例的弹性公网IP添加到其网络白名单中,确保源数据库可以与DRS实例互通。各厂商云数据库添加白名单的方法不同,请参考各厂商云数据库官方文档进行操作。以阿里云RDS MySQL为例,具体设置网络白名单的操作及注意事项可以参考相关指导。8. 配置源库信息和目标库数据库密码。配置源库信息,单击“测试连接”。当界面显示“测试成功”时表示连接成功。配置源库信息,单击“测试连接”。当界面显示“测试成功”时表示连接成功。9. 单击“下一步”。10. 在“迁移设置”页面,设置迁移用户和迁移对象。迁移用户:否迁移对象:全部迁移11. 单击“下一步”,在“预检查”页面,进行迁移任务预校验,校验是否可进行任务迁移。查看检查结果,如有不通过的检查项,需要修复不通过项后,单击“重新校验”按钮重新进行迁移任务预校验。预检查完成后,且所有检查项结果均成功时,单击“下一步”。12. 单击“提交任务”。返回DRS实时迁移管理,查看迁移任务状态。启动中状态一般需要几分钟,请耐心等待。当状态变更为“已结束”,表示迁移任务完成。说明:目前MySQL到GaussDB(for MySQL)迁移支持全量、全量+增量两种模式。如果创建的任务为全量迁移,任务启动后先进行全量数据迁移,数据迁移完成后任务自动结束。如果创建的任务为全量+增量迁移,任务启动后先进入全量迁移,全量数据迁移完成后进入增量迁移状态。增量迁移会持续性迁移增量数据,不会自动结束。确认迁移结果确认迁移结果可参考如下两种方式:DRS会针对迁移对象、用户、数据等维度进行对比,从而给出迁移结果,详情参见在DRS管理控制台查看迁移结果。直接登录数据库查看库、表、数据是否迁移完成。手工确认数据迁移情况,详情参见在GaussDB管理控制台查看迁移结果。在DRS管理控制台查看迁移结果1. 登录华为云控制台。2. 单击管理控制台左上角的,选择目标区域。3. 单击左侧的服务列表图标,选择“数据库 > 数据复制服务 DRS”。4. 单击DRS实例名称。5. 单击“迁移对比”,选择“对象级对比”,查看数据库对象是否缺失。6. 选择“数据级对比”,查看迁移对象行数是否一致。7. 选择“用户对比”,查看迁移的源库和目标库的账号和权限是否一致。在GaussDB管理控制台查看迁移结果1. 登录华为云控制台。2. 单击管理控制台左上角的,选择目标区域。3. 单击左侧的服务列表图标,选择“数据库 > 云数据库 GaussDB”。4. 选择GaussDB(for MySQL),单击迁移的目标实例的操作列的“登录”。5. 在弹出的对话框中输入密码,单击“测试连接”检查。6. 连接成功后单击“登录”。7. 查看并确认目标库名和表名等。确认相关数据是否迁移完成。
  • [集群&DWS] GaussDB(DWS) 负载管理简单介绍以及作业排队处理方法
    概述    数据库系统的负载管理和资源管理,在整个系统中起着很重要的作用,比如很多用户的业务压力过大时,有时会导致连接数量被占满,有时会导致某种计算资源被占满,有时会导致存储空间被占满,这些情况都会导致整个集群进入异常甚至不可用的状态:正在执行的作业互相争抢CPU,会导致大家都不能好好执行;大量作业执行时,占用大量内存,很容易触发到内存瓶颈,造成作业内存不可用问题,导致业务报错等等。在不进行并发控制的情况下,这些情况都很可能会出现,影响到正常业务。   本文用来总结一些GaussDB(DWS)在实际应用过程中,可能出现的各种作业排队的情况,以及出现排队时,我们应该怎么去判断是否正常,调整一些参数,让资源分配与负载管理更符合当前的业务;或者在作业阻塞的时候,怎么去处理这些情况,让业务立刻恢复正常。   本文分为以下几个小节去介绍并解答以上问题:  一、负载管理简介:双层排队简述  二、常用视图以及使用方法介绍  三、负载管理常见问题以及处理  四、部分负载管理配置方案介绍  五、小结一、负载管理简介:双层并发控制简述DWS的负载管理分为两层,第一层为cn的全局并发控制,第二层为资源池级别的并发控制。在通过第一层控制的时候,会继续向前走到第二层资源池控制,根据资源池当前的负载资源情况决定作业继续执行或者排队。DWS并发控制逻辑示意图如下:从本图的逻辑我们可以看到,实际作业执行中,可能会在两种队列中排队:一种是全局队列(global queue),这种队列不区分简单和复杂作业,也不区分是DDL或者是普通语句,一种是资源池队列(resource pool queue),用户下发的一般语句会根据资源消耗估算以及复杂程度在这里进行判断是否排队。在两层队列的过滤下,DWS会筛选出当前能执行的语句,使其正常运行,运行时也会受到其所属资源池资源的限制(只能使用资源池配置的CPU、内存、IO配额)。二、常用视图以及使用方法介绍这里介绍几个常用视图以及SQL语句,可以迅速判断目前的业务出现问题的原因,受限根据以下视图可以看到目前的作业是不是在排队,之后要迅速分析为什么在排队,是因为负载管理各个参数配置问题,还是因为正在执行的语句占据了过多的资源导致的排队。pgxc_stat_activity(pg_stat_activity)    常用语句:    #查询当前执行时间最长的语句的排队状态,query_id(数据库中作业的唯一标识),以及详细的语句信息。    select coorname,usename, current_timestamp-query_start as duration, enqueue,query_id,query from pgxc_stat_activity where state='active' and usename <> 'Ruby' order by duration desc;    根据该语句可以迅速判断出哪些语句执行时间很长,是什么样的语句执行很慢以及该语句的query_id,便于迅速进入下一步排查。    执行结果如下:上图解说:图中为在没有作业的情况下查询,可以看到有几个WLM的语句已经执行了很多,不过这两个是内部常驻线程,所以不影响业务,也不会占用连接数等数据库资源。其余的行可以看到有bi用户,在执行一些作业,时间大概1-6分钟左右。pg_session_wlmstat (记录每个cn的语句执行情况,资源使用情况,排队情况等信息)    常用语句:    #查询每个用户下的作业执行情况,排队情况以及作业的复杂情况和内存消耗情况。    select usename,enqueue,datname,status,attribute,count(*),sum(statement_mem) from pg_session_wlmstat group by 3,1,2,4,5 order by 1,3,4,5 ;    执行结果如下:上图解说:上图中说明当前连接的cn中有用户名为usr1的用户执行作业,并且在资源池上排队(第一节介绍的resourcepool队列),数据库为postgres,作业在排队所以当前status为pending状态。其他字段包括作业的属性和当前使用内存资源的总和情况(根据该数值可以看出是否因为内存资源不足而进入排队状态)。作业在排队时候不涉及到资源消耗,因此可能没有具体数值。pgxc_thread_wait_status(查看数据库中各个线程的执行情况,当前在等待哪一步骤执行完成,在哪个实例等待,都可以通过该视图查询);    常用语句:    #在根据pgxc_stat_activity查询到具体执行时间长的语句之后,可以根据本视图查询:    select * from pgxc_thread_wait_status where query_id = xxxxxxxx;    该语句可以查看执行慢语句的阻塞点,语句卡住时,可以通过该语句查看语句卡在了哪个步骤。    举例如下:    上图可以看到作业在wait io,此时可以检查下磁盘的读写速度是否,raid卡读写策略是否正常等等。    当出现排队的时候,wait_status一般的状态是waiting in ccn queue/waiting resourcepool queue等状态。查询并发数量的方法,就是查看pgxc_stat_activity中,状态(state字段)是active的语句,enqueue字段为null的语句,除此之外,idle in transaction之类状态的语句,也会占用一个并发数量,因为一个事务块的业务还未提交,自然也算是正在执行的业务,对于这种情况,后续可以考虑进行一个处于此类状态的超时时间的控制。三、负载管理常见问题一般当业务上发现任务阻塞时,可以从后台查询部分语句排查目前的情况,此时要先看下现象上是什么情况,一般并发控制有以下几种现象,暂时先列出这么多,后续继续补充:1.   业务反馈无法连接到数据库,比如DS连接一直转圈,过一段时间之后会超时报错。此时可以开始排查当前的配置情况,一般连接不到数据库,其实是一种表象,主要是因为作业已经进入了排队的状态,语句本身就有很多在排队,无法执行,此时用ds连接之后,ds本身就会下发语句查询一些系统表之类的信息,所以也会进入排队的状态,在客户层面的影响就是ds一直处于一个连接中的状态,实际上是ds的连接在数据库中。查询参数配置,看当前每个cn可以接受的最大并发数量是多少:show max_active_statements;如果当前cn的活跃作业超过这个参数,会出现语句排队的情况,主要排队情况为waiting in global queue,如下图所示,下图情况中,max_active_statements=6。查看业务连接是否主要只连接一个cn,可以同样通过查询pgxc_stat_activity判断coorname,查看是否大量的语句都是集中在某一个cn上执行,当语句下发集中在某个cn上时,这个cn的并发数量也只是max_active_statements设置的大小,举个例子:如果业务连接3个cn,每个cn的max_active_statements设置都是10,那么最大可以同时运行30个作业;如果这30个作业都下发到一个cn上,那么就有20个排队,同时只能执行10个,会大大影响执行效率,同时也会造成这种看似无法连接到该cn的现象。解决方法:业务负载不均:配置LVS,均衡业务,避免负载不均导致的排队。max_active_statements参数设置过小:在资源负载允许的情况下继续调大,如果资源达到瓶颈,继续放大可能会导致资源争抢,效果不大。连接被空闲事务占用:如上图中情况,可以看到有很多连接的状态都是idle in transaction,这种状态处于事务块完成但是没有提交,也会占用一个并发,导致其余作业并发量减小,导致排队。此类情况需要排查业务应用的执行情况,整改业务,避免处于这种空闲还占用并发的情况。严重阻塞业务的情况,紧急处理可以将该类语句直接terminate掉。确实已经有很多作业在执行,资源使用也已经达到一个瓶颈,这时候就需要去扩容或者降低业务量,来避免这种情况出现。2.   作业长时间执行不出来,并且有很多作业在排队,整体业务受到阻塞。此类情况可以继续使用上述查询pgxc_stat_activity的语句,查看语句的运行情况,结果可能如下:如图:图中最下方的两个作业,执行时间已经达到了11小时,但是仍然没有执行完,后面还有未执行的语句在排队。整体对于客户来说就是数据库已经hang死了,什么作业都执行不出来。排查步骤排查当前集群是否在使用动态自适应功能,查看如下参数:show enable_dynamic_workload; //查看该参数目前是否为打开状态(2020年的版本都是默认打开)如果该参数打开,那么就要查看这几个正在运行作业目前的内存使用情况,大概率正是因为这几个作业一直使用着内存不释放,才会出现整体的排队情况。通过连接cn 5001查询视图:select * from pg_session_wlmstat where threadid = $query_id;该视图可以看到某个语句使用了多大的内存,statement_mem字段可以看到我这个语句是使用了1G,但是实际情况中,1个语句使用几十个语句的情况很多。当一个或者几个语句的内存达到整个集群的总体可用内存上限,或者达到资源池上限的时候,就会使这些语句后面的语句开始排队。资源不放,排队不止。处理方法应急处理:及时将卡住的语句terminate,释放其占用的资源,后续进行优化之后再执行,优化手段很多,包括计划调优,analyze等操作,都可以避免一个语句占用太大内存,也可以提升执行效率。3.   全局资源可用内存很多,资源使用很小,并发数量也没有达到上限,但是查询显示很多作业处于排队状态。举例:查询pgxc_stat_activity时,语句的执行状态如下:可以看到,所有语句都在waiting in ccn queue,只有两个语句在运行。此时集群设置的max_active_statements是40,但是该用户实际活跃数量只有2个。举例:查询pgxc_stat_activity时,语句的执行状态如下:可以看到,所有语句都在waiting in ccn queue,只有两个语句在运行。此时集群设置的max_active_statements是40,但是该用户实际活跃数量只有2个。首先,出现出现waiting in ccn queue的情况,就一定是开启了内存自适应功能(enable_dynamic_workload=on)。此时只有两种情况,第一种是全局资源不足,会排队,第二种是用户所属的资源池内存不足,也会排队。根据图中的现象,我们看到很多语句都在排队,这时候要查询一个排队视图:select * from pg_stat_get_workload_struct_info();        这个视图可以清晰看到作业是在哪里排队:首先,上图中有totalsize,这个就是总体可用的最大内存,freesize_limit:执行语句可用的最大内存,freesize:当前可用的最大内存。所以可以得出结论,此时不是在全局排队,全局内存freesize足够,那么作业就是在资源池排队,资源池排队也会显示waiting in ccn queue。此时查询pg_session_wlmstat视图,可以看到正在运行的为dw用户,正在运行的语句占用的内存为两条各1G。可以通过界面或者后台查看一下,这个用户对应的租户上,是不是做了内存资源限制:查看租户界面内存配置如下:可以看到图中给这个租户或者说给这个用户所在的资源池配置了10%的内存配额,一共是2277MB,即2G左右。因此这种场景下,内存资源只能满足当前两个语句的执行,其余属于该用户的语句都会进行排队。处理办法:方法一、此类问题,若在资源允许的情况下,可以适当调大租户相关的内存资源,让更多语句能够同时运行。方法二、优化相关语句的执行效率,缩短执行时间,让语句可以高效执行,避免大量堆积。4.执行的作业基本都是一个用户的,其余用户的作业基本都在排队中无法执行。       举例:之前某局点出现高并发DDL的情况,该类高并发DDL在全局并发计数中会受到统计,占用max_active_statements中的并发数量。       比如:max_active_statements=20,其中某用户一直持续不停地下发DDL,此时在DWS设计ap场景并未涉及此类场景。会出现该20个并发设置普遍被该用户占用的情况,其他用户可能出现连不上的情况。       这种场景下,即时再调大并发,也会再被该用户的DDL语句占用。处理方案:针对高并发DDL的不合理业务场景进行优化,比如把连续创建删除临时表的动作,改为对永久表的操作,此时就可以极大幅度减少DDL并发数量,保证自身业务以及其余用户业务的正常连接和运行。四、部分场景配置方案1. 限制单用户并发       用户的作业分为以下几种,DDL/DML/以及常规查询,在DWS的视角中,常规查询有分为简单查询和复杂查询。       对于DWS的两层管控,受到第一层管控的有DDL、start transaction、DML、常规查询等,基本是所有语句,只有内部线程的语句(比如WLM线程)以及超级用户权限的用户执行的作业。       受到第二层管控的语句,主要是可以从优化器获取到具体执行计划以及执行代价的语句。除了DDL/start transaction 之类的语句,以及部分白名单语句,此类语句都是视为基本不消耗资源,并且不会造成阻塞的语句。       针对目前的管控机制来说,可以将单个用户关联到一个单独的资源池,这个资源池不设置内存配置,只设置并发配置,达到进行作业管控的效果。       具体步骤及解释如下:       1.在所有节点创建好控制组gs_ssh -c "gs_cgroup -c -S class_a"gs_ssh -c "gs_cgroup -c -S class_a -G workload_a"2.创建业务资源池(此时可以同步设置max_dop参数,active_statements会限制复杂作业的并发数量,max_dop参数会限制简单作业的并发数量)create resource pool p1 with (control_group="class_a:workload_a");alter resource pool p1 with (active_statements=10,mem_percent=0,max_dop=1);3.关联用户与该资源池ALTER USER testuser RESOURCE POOL 'p1';五、小结       并发管理的用处,主要是为了防止用户跑太多的作业,导致集群负载过大,资源发生争抢,系统不能稳定运行,会因为资源出现各种问题,CPU/内存/IO,哪一个都是让人头疼的问题,并发控制也可以同步控制某一个用户的并发作业,避免因为一个用户的作业数量太大,导致其他用户在使用数据库的时候出现问题。负载管理最主要的现象就是会出现作业排队的情况,排队是否合理,是否因为不合理的参数配置导致大量的业务阻塞;或者配置正常,但是没有达到上限就出现排队,本文的主要目的就是解决此类问题,或者及时定界到是什么原因导致了阻塞。       实际使用过程中,许多时候出现排队的情况,都可能和正在执行的语句有关,正在执行的语句占用着这个位置,又执行不完,其余语句自然会排队。因此我们碰到语句大量阻塞的情况,要迅速定界到是因为什么而造成阻塞,怎么样能恢复正常使用。找到问题的语句后,要及时去将它做一些适当的调优,避免再次执行到这个语句,还会出现一样的情况。
  • [POC&交付] 玩转GaussDB(DWS)资源负载管理系列 --- DWS资源负载管理的原理是什么,是怎么实现分布式资源管理的呢?
    文章目录多租户介绍计算资源:cpu管控计算资源:内存管控存储资源:磁盘空间正文一、什么是多租户?    所谓多租户:就是我们一套集群内,可以有多个用户使用,比如说云上,一个集群中有多个用户,大家都有自己的业务要运行,假如其中某个用户A运行了一些很吃资源的业务,一个人就把cpu、内存等资源用得淋漓尽致,那么其他人就只能看着了,自己的业务完全受阻,这时候,就需要多租户手段,去限制A用户所使用的资源,比如规定好让他最多使用1G的内存,最多使用30%的cpu,这样的话他的作业跑起来也不会影响到其他人,大家相安无事,好好工作。二、GaussDB for DWS多租户概述    GaussDB for DWS 用两层用户架构组织租户。一个父租户下有多个子租户,一个子租户只能属于一个父租户。我们通过给父租户分配资源配额,同时限定附属于该父租户的子租户的资源使用。其中,子租户也可以分配父租户分配到的资源。    主要涉及的资源有以下几种:    1)计算资源:CPU资源、内存资源。    2)存储资源:磁盘空间。    下面我们分别对各种资源的分隔方式进行一个技术分享。三、计算资源CPU资源管控   GaussDB for DWS的CPU管控机制,是基于linux自带机制:CGroup来实现的,CGroup是Linux内核提供的一种限制、记录、隔离进程组所使用的物理资源(如CPU、 Memory、I/O等)的机制。  我们以一种树的形式,组织各个分配了资源的租户,如下图所示:      图中是控制组的一个挂载树,从最上层开始,就分为了两部分,一部分是属于Gaussdb的资源,一部分是留给系统其他进程使用的资源,我们使用的资源如图所示,都是挂载到Gaussdb:gaussdba的,其中第一层又分为两个控制组,Backend用来预留资源给数据库常驻的各个工作线程,Class控制组的资源用来分配给各个用户进行作业执行。    我们每创建一个父租户,就会对应创建一个UserClass1-n挂载到Class控制组下,去从Class控制组分到对应配额的CPU资源。而我们创建的子租户,会从他们的父租户那里分配资源,当前我们支持两层的架构,父租户对应数据库中的组用户,子租户对应数据库中的业务用户。    总体来说可以这样表述:给父租户分配40%的CPU,此时子租户将父租户的40%当做100%来分配,比如子租户A设置配额为50%,那么实际上是相当于分配了整体CPU资源的40%*50%=20%。    2.内存资源管控     Gaussdb for DWS数据库当前的架构由最早的多进程架构,演变为多线程架构,因此单独一个数据库实例,比如一个coordinator或者datanode,都是作为一个进程运行,进程中会用多个线程去负责各种不同的工作,比如有的用来执行用户作业,有的用来处理后台的任务,各个cn与dn互相之间由一套独特的通信架构进行联络(基于TCP协议),由cn解析下发客户端发过来的作业,下推给dn去执行,结果再返回汇总到cn,完成各种业务。    DWS会直接在数据库进程启动的时候,就为其分配好内存,为实例分配的一整块内存中,会根据不同的需要,划分为各种不同的内存上下文,其中有一块内存,叫做dynamic_workload_memory,作为作业运行时可以使用的内存,总体大小也会在一开始被规定好,举个例子,整个进程分配到20G内存,可以给dynamic_workload_memory根据算法从中分配对应的内存,比如会分配20G中的15G用于作业执行。    而我们要说的多租户内存管控机制,就是从这15G的内存中,按照租户规定的百分比,对一个租户可以使用的资源进行限制。当给一个租户设置了一定额度的内存之后,数据库中会对他使用的内存进行一个记录,当他运行的作业所使用的内存要超过对应的内存的时候,就会不再执行,作业进入排队状态,等待资源释放之后再继续执行。四、存储资源    存储资源主要就是指磁盘空间上的管控,在实际使用的过程中,很容易出现由一条坏SQL一直执行,持续下盘,导致整个磁盘到达使用率100%的状态,后果非常严重,因此,DWS也为了避免出现这种状况,提供了磁盘管控的功能,在内核8.0版本中,一共提供了三种类型的磁盘空间管控:永久表空间管控、临时表空间管控、以及SQL执行时的算子罗盘使用的临时空间管控。日常使用过程中进行下盘的无非这三种场景,我们已经都可以对其进行磁盘额度限制,这个额度和用户绑定,我们在使用过程中,创建用户或者修改用户,都可以指定该用户可以使用的永久空间,临时表空间,算子落盘空间。使一个用户所使用的磁盘空间在可控制的范围内,一旦超过限制,该用户将不能再进行落盘的操作,并且如果是当前正在执行的语句导致的磁盘空间膨胀,数据库内核也会把他找到并且干掉。    具体内部机制可以这样描述:内核中会记录每个用户使用的空间大小,并且在用户进行落盘等使用到磁盘空间操作时也进行对应记录,直到用户所使用的空间达到限额时,内核就会做出对应的策略,不允许该用户再进行落盘。    此外,内核中还有一个保护机制,就是当某个dn实例使用率达到90%时,整个集群会进入只读状态,为防止磁盘达到100%后的未知后果,直接禁止所有的写入操作。五、后记    与此同时,对于用户所使用的资源,DWS也提供了监控功能,从页面上可以看到当前用户的资源使用情况,同样也可以在内核中查询视图:pg_total_user_resource_info进行查看。    希望通过本文可以加深读者对于DWS多租户功能的认识理解。
  • [POC&交付] 玩转GaussDB(DWS)线程管理问题系列(一) --- GaussDB for DWS线程残留定位手段
    【背景知识】DWS产品,基于公有云基础架构和平台的在线数据处理数据库,为用户提供海量数据挖掘和分析服务。主要提供不同行业的在线分析场景。如:增强ETL+实时BI分析、电商、IoT场景。当前的分布式架构,简单来说,是以多个组件分工负责不同的任务,构成整个集群,以下简单介绍部分组件,后续对各个组件详细介绍:CN:Coordinatornode,协调节点。客户端连接CN,发送SQL,CN接收解析后发送给所有DN执行,执行完后返回结果给CN,由CN统一返回给客户端。DN:Data node,数据存储节点,参与“本地数据”运算。GTM:全局事务管理器,系统中只有一个,采用主备方式,多线程架构。主要用来管理Id和快照信息,保证系统中全局事务的一致性。由于DWS是分布式架构,所以会涉及到整个集群的各个节点之间的互相通信,建立连接等通信相关功能,对于通信我们也有完善的一套架构方案,此处要知道的是我们通过cn与dn之间建立连接,互相通信,完成整个作业的执行,执行完作业之后,该连接会被回收。         本文就是介绍曾经某个据点出现过的一个cn进行了进程kill,此时cn进程的连接清理之后,dn有连接的时候,可以使用的分析定位手段。【视图介绍】pg_stat_activity:查询作业执行情况。pg_thread_wait_status:查询节点各个线程执行等待的情况。【定位手段】针对dn是否有线程残留,可以采用以下方法进行定位。1、确定是否是dn线程残留,如dn_6015_6016,表为postgres,cn查以下视图:select count(*) from pgxc_thread_wait_status where node_name='dn_6015_6016' and db_name='postgres' and thread_name='cn_5001' and  tlevel=0;解释:tlevel = 0代表stream处理层的上层,表示cn和dn之间的连接。select count(*) from pg_pooler_status where node_name='dn_6015_6016' and database='postgres'解释:查看此时dn_6015_6016的对应连接数量。此视图只能在cn查询,显示本地cn的pooler模块连接缓存信息。二者结果不同:第二个语句查询结果大于第一个语句。可以说明有连接残留。2、若发生线程残留,从pgxc_thread_wait_status 视图中找到dn上残留的线程号(即比pooler视图中多的线程号),ssh 到dn_6015_6016所在机器,登录到dn_6015_6016select * from pg_stat_activity where pid=?;解释:用该视图可以查询到client_port,client_port是与当前实例用于TCP连接的后台客户端的端口号。找到端口号例如:50079 、44101。3、在当前线程残留dn查看该端口号状态,使用netstat命令,查看对端ip。如下:Netstat –anop | grep 50079可以得到类似如下结果:解释:一个连接由一个五元组唯一确定:协议名(tcp),本端ip,本端端口号,对端ip,对端端口号,决定,与图中对应。(a:所有有效连接 n:使用ip地址代替名称 p:显示建立相关连接的程序名和PID  o:显示与网络计时器相关信息)当前图片中可以看到,对端是192.100.12.6:50079,此时可以ssh到对端,查看是否是cn,并且用同样命令:netstat -anop|grep 50079查看cn节点的进程号是否与上述命令结果中的连接中的相同:连接进程号即结果中xxxxx/gaussdb的xxxxx。如上图中的1240/gaussdb,1240即进程号。cn进程号可以通过:ps aux | grep coo查看。如下:此时可以判断该连接是由cn建立,与dn连接。此时确定连接还是有在使用的。【更换思路】一、这个时候线索断了,换一种思路,以dn上作业开始执行的时间对应在cn查询:cn_5003上执行:select * from pg_stat_activity order by query_start;这里发现有语句可以用开始的时间可以和dn上的作业开始时间对应上,并且语句完全一样,只是此时的queryid已经被置为0(因此一开始在cn没有查到),并且状态是idel in transaction,这个状态代表事务未提交。二、此时查看对应线程的cn和dn之间的连接视图(前面有结果):可以看到对应线程号还是 inuse状态,表明连接不是残留。三、根据cn上的连接client_port,继续看当前是谁连接了该cn,占用连接:这里发现是有java进程一直占用连接,说明客户的客户端一直在连接事务一直没有commit。【问题解决】是客户的误操作,不是连接残留,但是既然客户有疑问,那就要分析清楚。此篇博文可应用于所有连接残留问题定位分析。
  • [POC&交付] GaussDB for DWS Hang问题定位指南
    1 Hang问题基础知识GaussDB for DWS 为分布式数据库,通常由于单节点亚健康、系统资源紧张或查询本身的计划等问题,造成系统疑似发生Hang。Hang问题的产生原因由很多种,比如,死锁等待、日志同步等待、事务超时、通信故障、数据溢出发生死循环等等,更为常见的是由于执行慢、中间结果集倾斜而导致的疑似Hang。掌握Hang问题的基本定位方法对于大集群环境下快速找准疑似阻塞点,修复故障环境或优化执行性能是至关重要的。1.1 常用视图目前,GaussDB for DWS对外提供诸多系统视图,可以用来辅助Hang问题的分析定位,常用视图及用法说明如下表所示。(☆代表常用程度) pgxc_stat_activity ☆☆☆查询当前集群所有DN实例上各个session的信息,重点关注正在执行(state状态为active)的SQL。我们一般首先分析pgxc_stat_activity中的内容,初步根据执行时间筛选出疑似query,然后使用此query的query_id和视图pgxc_thread_wait_status结合,获取此query集群级别的线程状态进行hang问题分析。 注:此视图需要以超级用户的身份来运行 在问题分析时,我们首先需要客户反馈的疑似hang的作业的信息,根据作业所在的databse、运行作业的用户身份、运行作业客户端以及运行作业所连接的实例CN名称初步筛选出问题SQL的运行信息,具体运行信息见附件中字段含义解释。比如疑似hang作业是以omm用户运行在postgres数据库连接到cn_5001实例上运行的,我们使用如下SQL进行作业状态查询 我们可以根据上述返回的结果,结合作业运行的客户端名称、客户端ip、作业query运行开始时间query_start进一步筛选出疑似hang作业。 【附:视图各字段含义】字段名称数据类型字段描述coornametext运行业务SQL的CN节点名称datidoid用户会话在后台连接到的数据库OID。datnamename用户会话在后台连接到的数据库名称。可以看到此语句实际在哪个数据库运行,来帮助区分是什么业务。pidbigint后台线程ID。即运行此SQL的线程的线程号,此线程号在pg_thread_wait_status/pg_locks等视图中也存在,可以用这个线程号来与这些视图进行关联。usesysidoid登录该后台的用户OID。usenamename登录该后台的用户名。执行此SQL的用户名,可以用来确认是什么用户调起的业务。application_nametext连接到该后台的应用名。应用名称,一般有三种:l gsql:此SQL是从gsql客户端发起l Data Studio:从Data Studio客户端发起的SQLl cn_50XX:代表从远端CN发送过来的SQL语句,一般出现在DDL、DCL、analyze、vacuum作业场景下l 其它:其它业务客户端发起的业务连接,如果应用程序未显式命名application_name,数据侧一般显式为unkonwnclient_addrinet连接到该后台的客户端的IP地址。 如果此字段是null,它表明通过服务器机器上UNIX套接字连接客户端或者这是内部进程(如autovacuum)。可以用来确定是从哪个机器发起的连接,进而帮助确认是什么业务发起的语句client_hostnametext客户端的主机名,这个字段是通过client_addr的反向DNS查找得到。这个字段只有在启动log_hostname且使用IP连接时才非空。client_portinteger客户端用于与后台通讯的TCP端口号,如果使用Unix套接字,则为-1。通过此字段圈定业务SQL发起客户端backend_starttimestamp with time zone该后台线程启动的时间,即当客户端连接到服务器的时间。xact_starttimestamp with time zone启动当前事务的时间,如果没有事务是活跃的,则为null。如果当前查询是首个事务,则这列等同于query_start列。如果启用了显式事务,即使用begin/start transaction等开启了一个事务,则此字段代表事务开始的时间。query_starttimestamp with time zone开始当前活跃SQL的开始时间, 如果state的值不是active,则这个值是上一个SQL的开始执行时间state_changetimestamp with time zone上次state字段值变化的时间。waitingboolean如果后台当前正等待锁则为true,否则为falseenqueuetext工作负载管理资源状态。· 语句当前的排队情况,包括:· Global::在全局队列中排队。 · Respool:在资源池队列中排队。 · CentralQueue:在中心协调节点(CCN)中排队。 · Transaction:语句处于一个事务块中排队。 · StoredProc : 语句处于一个存储过程中排队。 · None:未在排队。 · Forced None : 事务块语句或存储过程语句由于超出设定的等待时间而强制执行。上面这些状态表明了当前语句的排队情况,如果处在排队状态,语句是不在执行的,也不会占用系统资源。statetext该后台当前总体状态。状态值可能是如下的一种:· active:后台正在执行一个作业。 · idle:后台线程空闲,且不在一个事务块中。 · idle in transaction:后台线程空闲,且在事务块中· idle in transaction (aborted):后台线程空闲,且后台线程在事务块中有语句执行失败且没有执行rollback命令 · fastpath function call:后台正在执行一个fast-path函数。 · disabled:如果后台禁用track_activities,则报告这个状态。resource_poolname用户作业关联的资源池。query_idbigint查询语句的ID。当前语句的唯一标识,可以用此字段与pg_thread_wait_status关联。进一步进行问题分析定位querytext该后台的最新查询。如果state状态是active(活跃的),此字段显示当前正在执行的查询。所有其他情况表示上一个查询。语句默认仅显示1024字节。 pgxc_thread_wait_status  ☆☆☆☆☆查询集群全局所有线程的层次调用关系及阻塞等待情况,通常在视图查询语句增加其他过滤条件(比如根据pgxc_stat_activity筛选出来的疑似hang的SQL的query_id),缩小关注排查范围。【附:视图各字段含义】字段名称数据类型字段含义描述node_nametext实例的名称。db_nametext数据库名称。thread_nametext线程名称。query_idbigint业务SQL的ID编号,同一条SQL对应的所有的执行线程的query_id是相同的,与pg_stat_activity中query_id一致tidbigint当前线程的线程号。与pgxc_stat_activity中的pid、pg_locks中的pid一致lwtidinteger当前线程的轻量级线程号。使用此线程号可以在所在节点上进行gstack获取此线程运行栈信息ptidintegerstreaming线程的父线程号tlevelintegerstreaming线程的层级。与执行计划的层级(id)相对应。smpidintegersmp执行模式下并行线程的并行编号。wait_statustext当前线程的等待状态。等待状态的详细信息请参见资料。一般常见的状态有:wait node:dn_xxxx_xxxx:表示在等待某个DNnone:表示正在执行,没有等待任何其他节点acquire lock :表示正在等待锁。这时需要到对应节点上查看pg_locks视图。 pg_thread_wait_status  ☆☆☆☆单个实例上所有作业线程的层次调用关系及阻塞等待情况,在大集群复杂query问题定位时,视图pgxc_thread_wait_status返回的信息过多,会对问题定位形成一定干扰,这时可以在CN上通过execute direct on语法获取指定dn实例的作业线程信息。比如要获取dn_6001_dn_6002节点的作业线程调用信息 pgxc_comm_recv_stream  ☆☆☆查询集群所有DN的通信库接收流状态,辅助通信层发生收发Hang的排查定位。pgxc_comm_send_stream  ☆☆☆查询集群所有DN的通信库发送流状态,与pgxc_comm_recv_stream视图结合使用,来定位通信层的收发Hang问题。pgxc_prepared_xacts  ☆☆查询集群中所有节点的启动事务信息,辅助事务超时场景下的Hang问题定位,通过查询该视图获取gxid,然后结合pgxc_xacts_iscommitted(gxid)可以获知事务是否提交。pgxc_running_xacts  ☆☆查询集群中所有节点的运行事务信息。pg_locks  ☆☆查询当前实例的锁状态,辅助死锁等待的Hang问题定位。名称类型引用描述locktypetext-被锁定对象的类型:relation,extend,page,tuple,transactionid,virtualxid,object,userlock,advisory。databaseoidPG_DATABASE.oid被锁定对象所在数据库的OID。· 如果被锁定的对象是共享对象,则OID为0。 · 如果是一个事务ID,则为NULL。relationoidPG_CLASS.oid表的OID,如果锁定的对象不是表,也不是表的一部分,则为NULL。锁等待一般都是等待表的锁,用relation做条件可以看到当前的表锁被谁持有。pageinteger-关系内部的页面编号,如果对象不是关系页或者不是行页,则为NULL。tuplesmallint-页面里边的行编号,如果对象不是行,则为NULL。virtualxidtext-事务的虚拟ID,如果对象不是一个虚拟事务ID,则为NULL。transactionidxid-事务的ID,如果对象不是一个事务ID,则为NULL。classidoidPG_CLASS.oid包含该对象的系统表的OID,如果对象不是普通的数据库对象,则为NULL。objidoid-对象在其系统表内的OID,如果对象不是普通数据库对象,则为NULL。objsubidsmallint-对于表的一个字段,这是字段编号;对于其他对象类型,这个字段是零;如果这个对象不是普通数据库对象,则为NULL。virtualtransactiontext-持有此锁或者在等待此锁的事务的虚拟ID。pidbigint-持有或者等待这个锁的服务器线程的逻辑ID。如果锁是被一个预备事务持有的,则为NULL。语句pid,可以看到这个pid是在等待哪几各锁,持有哪几各锁。modetext-这个线程持有的或者是期望的锁模式。grantedboolean-· 如果锁是持有锁,则为TRUE。 · 如果锁是等待锁,则为FALSE。表示锁被谁持有fastpathboolean-如果通过fast-path获得锁,则为TRUE;如果通过主要的锁表获得,则为FALSE。 pgxc_node  ☆☆查询集群中所有实例节点信息,重点关注节点的node_name, node_port, node_id。除过上述常用视图,Hang问题定位过程需要根据实际场景,结合执行计划、gstack工具、系统日志等共同分析定位。1.2 简单示例比如在执行create table的时候疑似发生hang,那么我们可以执行以下操作定位问题1. 获取疑似hang的SQL的query_idselect * from pgxc_stat_activity where state = ‘active’ and lower(query) like ‘create table %’;2. 获取此作业的线程等待关系select * from pgxc_thread_wait_status where query_id = xx;xx:为上一步获取的疑似hang的SQL的query_id值 分析此query_id相关的线程的状态(字段wait_status),查看是否有acquire lock状态的线程,找到其node_name 和 tid字段3. 到对应的node_name上获取锁信息execute direct on (xx) ‘select * from pg_locks where pid = xxx’;--xx: 上一步获取的node_name字段的值--yy:上一步获取的tid字段值。获取等待加锁的表信息(字段relation)4.到对应的node_name上获取此表的持锁信息execute direct on (xx) ‘select * from pg_locks where relation = yy and granted = true’;--xx: 第二步获取的node_name字段的值--yy: 第三步获取的等待加锁字段的值获取持锁的线程(字段pid)5.获取持锁的作业信息select * from pgxc_stat_activity where pid=xx;--xx: 第四步获取持锁线程信息字段query的内容即为持锁线程信息,也是阻塞create table语句的作业信息 2 Hang问题分类客户侧感知的hang分为三种1. 真实hang一般是轻量级锁缺陷、执行链路环状或者死循环执行。这种场景下作业永远无法执行完2. 执行慢:业务执行慢,远远超出客户的预期,客户侧产生hang的认知效果。这种问题最终需要通过调优解决3. 锁等待:因抢占不到锁资源,导致作业排队等待加锁。这种场景的表现是要么作业执行时间边长,要么等待一段时间(一般为20min)之后报锁超时的失败信息 根据以往的经验,局点常见的hang问题有以下几种3 Hang问题定位方法及解决措施3.1 基本步骤Step1. cm_ctl query查询集群当前状态,确保集群状态正常;Step2. gsql连接数据库,执行select * from pgxc_stat_activity,查询目标查询的query_id,有时候可以增加where state = ‘active’筛选活跃SQL;Step3. 执行select * from pgxc_thread_wait_status where query_id = xxx,查询集群全局与之关联的所有线程的层次调用关系及阻塞等待情况。自上而下,逐层分析,确定疑似阻塞节点及线程信息,甚至,可以绘制线程等待关系图,更加直观地分析当前Hang问题的根因。除此,可结合执行计划或gstack查看线程堆栈,进一步佐证定位结论。Step4. 如果Step3仍无定论,则针对其他常见Hang场景(目前以锁等待和通信收发等待最为常见),结合2.1节相应视图,进一步分析定位:a) 锁等待:从Step3的查询结果分析线程等待关系,如果阻塞线程状态为acquire lock,则进一步执行select * from pg_locks where pid = xxx查询阻塞线程的加锁情况;b) 通信层数据收发成环:从Step3的查询结果分析线程等待关系,如果阻塞线程状态一直为flush data: wait quota,则可能是通信层收发过程hang死,继续执行select * from pgxc_comm_send_stream和select * from pgxc_comm_recv_stream,可以根据Step3的查询结果增加where条件限定node_name、remote_name、query_id、pn_id(即plevel),进一步排查wait quota的根因是否是发送端或接收端数据流异常或者通信问题等。
  • [POC&交付] 详解GaussDB for DWS数据库查询关联的广播和重分布
    当两张表关联的时候,如果一张表关联的不是分布列,那么就会发生表的广播或者重分布,将数据移到一个节点上进行关联,从而获得数据。这里详细的介绍什么时候广播,什么时候重分布。 分布式的关联有两种:(1) 单DN关联。关联键与分布列一致,只要在单个库关联后得到结果即可。(2)跨DN关联。关联键与分布列不一致,需要数据重分布,转换成单库关联查询,从而实现表的关联。 不管是采用广播还是重分布首先必须保证结果的正确性,其次才考虑性能。下面将从内连接、左连接、全连接三中连接情况进行分析:                测试表a和b的定义表名                字段              分布列       记录数 a       seqnum bigint ,rd1 int       seqnum        M b       seqnum bigint, rd1 int       seqnum        N create table a(seqnum int, rd1 int);create table b(seqnum int, rd1 int); 1 内连接1.1 情况1:关联列为分布列    select * from  a,b where a.seqnum=b.seqnum;    carl=# explain select * from  a,b where a.seqnum=b.seqnum;                                QUERY PLAN                                ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=117.74..737.59 rows=10000 width=24)   Node/s: All datanodes   ->  Hash Join  (cost=113.74..399.18 rows=10000 width=24)         Hash Cond: (b.seqnum = a.seqnum)         ->  Seq Scan on b  (cost=0.00..236.17 rows=131000 width=12)         ->  Hash  (cost=103.33..103.33 rows=10000 width=12)              ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(7 rows)1.2 情况2:表a的关联键是分布列,表b的关联键不是分布列   select * from  a,b where a.seqnum=b.rd1;通过两种方式进行关联:(1)表b按照rd1字段将数据重分布到各个节点上,然后再与表a进行关联。重分布的数据量是N。carl=# explain select * from  a,b where a.seqnum=b.rd1;                                      QUERY PLAN                                      ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=117.74..1551.39 rows=10007 width=24)   Node/s: All datanodes   ->  Hash Join  (cost=113.74..1212.58 rows=10007 width=24)         Hash Cond: (b.rd1 = a.seqnum)         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..1053.00 rows=120000 width=12)               Spawn on: All datanodes               ->  Seq Scan on b  (cost=0.00..228.00 rows=120000 width=12)         ->  Hash  (cost=103.33..103.33 rows=10000 width=12)               ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(9 rows)  (2)将表a广播,每一个节点一份全量数据,然后再与表b进行关联。广播的数据量是M*DN个数carl=# explain select * from  a,b where a.rd1=b.rd1;                                    QUERY PLAN                                    ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=376.63..1635.37 rows=10007 width=24)   Node/s: All datanodes   ->  Hash Join  (cost=372.63..1296.56 rows=10007 width=24)         Hash Cond: (a.rd1 = b.rd1)         ->  Streaming(type: BROADCAST)  (cost=0.00..878.09 rows=120000 width=12)               Spawn on: All datanodes               ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)         ->  Hash  (cost=236.17..236.17 rows=131000 width=12)               ->  Seq Scan on b  (cost=0.00..236.17 rows=131000 width=12)(9 rows) 若a表的数据量(M)大于b表的数据量(N)时,则永远是使用表b重分布方式。 若a表的数据量(M)小于b表的数据量(N)时,当(N-M)> M*DN个数时,将表a广播到每一个节点上,再与表b进行关联;当(N-M)<M*DN个数时,则将表b重分布到各个节点上,再与表a进行关联。1.3  情况3:表a的关联键不是分布列,表b的关联键不是分布列 当 MAX(M,N)> MIN(M,N)*DN个数时,将表a(MIN(M,N)行数少的表)广播到每一个节点上,再与表b(MAX(M,N)行数较多的表)进行关联,广播的的代价是MIN(M,N)*DN个数 carl=# explain select * from  a,b where a.rd1=b.rd1;                                    QUERY PLAN                                    ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=374.74..1633.48 rows=10011 width=24)   Node/s: All datanodes   ->  Hash Join  (cost=370.74..1294.67 rows=10011 width=24)         Hash Cond: (a.rd1 = b.rd1)         ->  Streaming(type: BROADCAST)  (cost=0.00..878.09 rows=120000 width=12)               Spawn on: All datanodes               ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)         ->  Hash  (cost=235.33..235.33 rows=130000 width=12)               ->  Seq Scan on b  (cost=0.00..235.33 rows=130000 width=12)(9 rows) 当 MAX(M,N)< MIN(M,N)*DN个数时,则将表a,表b分别重分布到各个节点上,重分布的代价是M+Ncarl=# explain select * from  a,b where a.rd1=b.rd1;                                        QUERY PLAN                                        ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=186.46..1543.71 rows=10026 width=24)   Node/s: All datanodes   ->  Hash Join  (cost=182.46..1204.08 rows=10026 width=24)         Hash Cond: (b.rd1 = a.rd1)         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..978.74 rows=110500 width=12)               Spawn on: All datanodes               ->  Seq Scan on b  (cost=0.00..219.08 rows=110500 width=12)         ->  Hash  (cost=172.05..172.05 rows=10000 width=12)               ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..172.05 rows=10000 width=12)                     Spawn on: All datanodes                     ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(11 rows)2 左连接2.1 情况1:关联列为分布列select * from  a left join b  on a.seqnum=b.seqnum;carl=# explain select * from  a left join b  on a.seqnum=b.seqnum;                                QUERY PLAN                                ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=117.74..880.05 rows=14439 width=24)   Node/s: All datanodes   ->  Hash Right Join  (cost=113.74..391.33 rows=14439 width=24)         Hash Cond: (b.seqnum = a.seqnum)         ->  Seq Scan on b  (cost=0.00..228.04 rows=120050 width=12)         ->  Hash  (cost=103.33..103.33 rows=10000 width=12)               ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(7 rows)2.2   情况2:表a的关联键是分布列,表b的关联键不是分布列  不管表b有多大,表b的数据总是被重分布 carl=# explain select * from  a left join b  on a.seqnum=b.rd1;                                      QUERY PLAN                                      ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=130.87..1411.37 rows=1001 width=24)   Node/s: All datanodes   ->  Hash Right Join  (cost=126.87..1377.65 rows=1001 width=24)         Hash Cond: (b.rd1 = a.seqnum)         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..1206.20 rows=140000 width=12)               Spawn on: All datanodes               ->  Seq Scan on b  (cost=0.00..243.67 rows=140000 width=12)         ->  Hash  (cost=125.83..125.83 rows=1000 width=12)               ->  Seq Scan on a  (cost=0.00..125.83 rows=1000 width=12)  carl=# explain select * from  a left join b  on a.seqnum=b.rd1;                                       QUERY PLAN                                        ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=172.72..4468.55 rows=120000 width=24)   Node/s: All datanodes   ->  Hash Left Join  (cost=168.72..406.05 rows=120000 width=24)         Hash Cond: (a.seqnum = b.rd1)         ->  Seq Scan on a  (cost=0.00..199.00 rows=120000 width=12)         ->  Hash  (cost=167.68..167.68 rows=1000 width=12)               ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..167.68 rows=1000 width=12)                     Spawn on: All datanodes                     ->  Seq Scan on b  (cost=0.00..160.83 rows=1000 width=12)(9 rows)2.3 情况3:表a的关联键不是分布列,表b的关联键不是分布列 表a和表b则会分别按字段rd1重分布,再关联carl=# explain select * from  a left join b  on a.rd1=b.rd1;                                        QUERY PLAN                                        ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=186.46..1703.34 rows=10009 width=24)   Node/s: All datanodes   ->  Hash Right Join  (cost=182.46..1364.52 rows=10009 width=24)         Hash Cond: (b.rd1 = a.rd1)         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..1132.94 rows=130500 width=12)               Spawn on: All datanodes               ->  Seq Scan on b  (cost=0.00..235.75 rows=130500 width=12)         ->  Hash  (cost=172.05..172.05 rows=10000 width=12)               ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..172.05 rows=10000 width=12)                     Spawn on: All datanodes                     ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(11 rows)3 全连接3.1 情况1:关联列为分布列   carl=# explain select * from  a full  join b  on a.seqnum=b.seqnum;                                QUERY PLAN                                ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=117.74..4830.17 rows=130500 width=24)   Node/s: All datanodes   ->  Hash Full Join  (cost=113.74..412.20 rows=130500 width=24)         Hash Cond: (b.seqnum = a.seqnum)         ->  Seq Scan on b  (cost=0.00..235.75 rows=130500 width=12)         ->  Hash  (cost=103.33..103.33 rows=10000 width=12)               ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(7 rows) 3.2 情况2:表a关联键是分布列,表b关联键不是分布列       表b数据被重分布到各个节点上,再与表a关联carl=# explain select * from  a full  join b  on a.seqnum=b.rd1;                                      QUERY PLAN                                      ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=117.74..5727.36 rows=130500 width=24)   Node/s: All datanodes   ->  Hash Full Join  (cost=113.74..1309.39 rows=130500 width=24)         Hash Cond: (b.rd1 = a.seqnum)         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..1132.94 rows=130500 width=12)               Spawn on: All datanodes               ->  Seq Scan on b  (cost=0.00..235.75 rows=130500 width=12)         ->  Hash  (cost=103.33..103.33 rows=10000 width=12)               ->  Seq Scan on a  (cost=0.00..103.33 rows=10000 width=12)(9 rows)3.3 情况3: 表a的关联键不是分布列,表b的关联键不是分布列表a和表b则会分别按字段rd1重分布,再关联carl=# explain select * from  a full  join b  on a.rd1=b.rd1;                                        QUERY PLAN                                        ----------------------------------------------------------------- Streaming (type: GATHER)  (cost=213.47..6179.47 rows=140000 width=24)   Node/s: All datanodes   ->  Hash Full Join  (cost=209.47..1439.75 rows=140000 width=24)         Hash Cond: (a.rd1 = b.rd1)         ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..1178.20 rows=140000 width=12)    Spawn on: All datanodes               ->  Seq Scan on a  (cost=0.00..215.67 rows=140000 width=12)         ->  Hash  (cost=199.05..199.05 rows=10000 width=12)               ->  Streaming(type: REDISTRIBUTE)  (cost=0.00..199.05 rows=10000 width=12)                     Spawn on: All datanodes                     ->  Seq Scan on b  (cost=0.00..130.33 rows=10000 width=12)(11 rows)
  • [POC&交付] Gauss DB(DWS)权限管理场景总结
    GaussDB(DWS) 使用默认权限机制,数据库对象创建后,进行对象创建的用户就是该对象的所有者。集群安装后的默认情况下,未开启三权分立,数据库系统管理员具有与对象所有者相同的权限。也就是说对象创建后,默认只有对象所有者或者系统管理员可以查询、修改和销毁对象,以及通过GRANT将对象的权限授予其他用户。为使其他用户能够使用对象,必须向用户或包含该用户的角色授予必要的权限。说在前面:每个实例可以多个db,每个db有自己的owner,每个db下可以建立多个schema,每个schema有自己的owner,每个schema下可以创建多张表,每张表都有自己的owner。db owner不一定能操作其下面的某个schema。schema owner不一定能操作其下面的某张表。支持以下的权限:SELECT、INSERT、UPDATE、DELETE、TRUNCATE、REFERENCES、CREATE、CONNECT、EXECUTE和USAGE。不同的权限与不同的对象类型关联。要撤消已经授予的权限,可以使用REVOKE。对象所有者的权限(例如ALTER、 DROP、GRANT和REVOKE)是隐式的,无法授予或撤消。即只要拥有对象就可以执行对象所有者的这些隐式权限。对象所有者可以撤消自己的普通权限,例如,使表对自己以及其他人只读。系统表和系统视图要么只对系统管理员可见,要么对所有用户可见。标识了需要系统管理员权限的系统表和视图只有系统管理员可以查询。数据库提供对象隔离的特性,对象隔离特性开启时,用户只能查看有权限访问的对象(表、视图、字段、函数),系统管理员不受影响。系统视图中涉及用户、角色及权限相关的视图有 pg_user、pg_authid、pg_roles、pg_auth_members,其中pg_user只存储用户信息;pg_authid存储有关数据库认证标识符(角色)的信息、pg_roles视图提供访问数据库角色的相关信息;pg_auth_members存储角色的成员关系,即某个角色组包含了哪些其他角色。一个用户实际上就是一个rolcanlogin标志被设置的角色。任何角色(不管rolcanlogin设置与否)都能够把其他角色作为成员。在一个集群中只有一份pg_authid,不是每个数据库有一份。需要有系统管理员权限才可以访问此系统表。场景案例:场景一:查询数据对象上用户或角色的权限情况(对象维度)查询方法:SELECT relname,relacl FROM pg_class where relname='tablename';示例:注释:rolename=xxxx/yyyy  --赋予一个角色的权限=xxxx/yyyy  --赋予public的权限xxxx表示赋予的权限,yyyy表示授予该权限的角色。参数说明:场景二:查询用户及角色具有的权限情况(用户维度)查询方法:select * from information_schema.table_privileges where grantee='user';示例:注释:grantor :赋权用户grantee:被赋权用户table_catalog:数据库名table_schema:模式名table_name:对象名privilege_type:被赋予的权限场景三:创建新用户,把归属其他用户的对象的权限赋予新用户赋权顺序:数据库-->模式-->对象赋权方法:--首先赋予用户数据库的连接权限(此权限默认开启)grant CONNECT ON DATABASE <database> to <user>;-- 赋予用户指定schema的usage权限GRANT   USAGE ON SCHEMA <schema> TO <user>;--赋予用户当前schema下所有表及视图的增删改查权限GRANT SELECT,INSERT,UPDATE,DELETE,truncate  ON  ALL TABLES IN SCHEMA <schema> to <user>;--赋予用户当前schema下后续新建的表及视图的增删改查权限(默认情况下匹配schema归属用户所建的表的权限)alter default privileges in schema <schema> grant SELECT,INSERT,UPDATE,DELETE,truncate on tables to <user>;--赋予用户当前schema下后续新建的表及视图的增删改查权限(指定用户所建的表的权限)alter default privileges for user <user>  in schema <schema> grant SELECT,INSERT,UPDATE,DELETE,truncate on tables to <user>;--赋予用户当前schema下所有函数及存储过程的执行权限GRANT  EXECUTE   ON   ALL FUNCTIONS IN SCHEMA <schema> to  <user>;--赋予用户当前schema下所有序列的查询及使用权限grant USAGE,SELECT on ALL SEQUENCES IN SCHEMA <schema> to <user>;场景四:只读用户赋权赋权顺序:数据库-->模式-->对象赋权方法:--首先赋予用户数据库的连接权限(此权限默认开启)grant CONNECT ON DATABASE <database> to <user>;-- 赋予用户指定schema的usage权限GRANT   USAGE ON SCHEMA <schema> TO <user>;--只赋予用户当前schema下所有表及视图的查询权限GRANT SELECT  ON  ALL TABLES IN SCHEMA <schema> to <user>;--赋予用户当前schema下后续新建的表及视图的增删改查权限(默认情况下匹配schema归属用户所建的表的权限)alter default privileges in schema <schema> grant SELECT,INSERT,UPDATE,DELETE,truncate on tables to <user>;--赋予用户当前schema下后续新建的表及视图的增删改查权限(指定用户所建的表的权限)alter default privileges for user <user>  in schema <schema> grant SELECT,INSERT,UPDATE,DELETE,truncate on tables to <user>;--赋予用户当前schema下所有函数及存储过程的执行权限GRANT  EXECUTE   ON   ALL FUNCTIONS IN SCHEMA <schema> to  <user>;--赋予用户当前schema下所有序列的查询及使用权限grant USAGE,SELECT on ALL SEQUENCES IN SCHEMA <schema> to <user>; 场景五:用户/角色的权限赋给其他用户/角色创建角色,赋予了login权限,则相当于创建了用户,如果没有赋予login权限,则这个角色只能在pg_roles里面看到,而在pg_user里面看不到。实际业务场景中可以把用户/角色的权限继承给另一个用户/角色,赋予语法:grant u1 to u2;查询某个用户/角色是否继承了其他用户、角色的权限,方法如下:select * from pg_roles where rolname in ('u1','u2','u3');rolinherit字段为t表示改角色继承了其他角色的权限。查询用户/角色之间继承关系,查询方法如下:select  m.rolname,m.member as member,b2.rolname as grantor,m.admin_option from (select g.rolname,b1.rolname as member,g.grantor,g.admin_option  from (select a.roleid,b.rolname,a.member,a.grantor,a.admin_option from PG_AUTH_MEMBERS a, pg_roles b where a.roleid=b.oid) g ,pg_roles b1 where g.member=b1.oid)m ,pg_roles b2 where  m.grantor =b2.oid ;示例:注释:rolname :拥有成员的角色名。member:   属于成员的角色名。grantor :    赋予此成员关系的角色名。admin_option: 如果有权限可以把ROLEID角色的成员关系赋予其他角色,则为真。场景六:获取用户对Schema 权限信息实际使用场景中,例如业务迁移中,用户需要统计出哪些用户对当前schema具有权限,请参照下述方法查询:通过查询PG_NAMESPACE系统视图中nspacl字段获取用户对schema的权限信息:例如:如下图,user01用户对myschema具有Usage权限及CREATE权限,readuser用户对myschema具有Usage权限。当用户及schema数量很多时,梳理权限信息科参照以下脚本:SELECT pn.nspname AS schema_name,    COALESCE(NULLIF(role.name, ''::name), 'PUBLIC'::name) AS grantee,    "substring"(        CASE            WHEN "position"(split_part(split_part(','::text || array_to_string(pn.nspacl, ','::text), (','::text || role.name::text) || '='::text, 2), '/'::text, 1), 'U'::text) > 0 THEN ',USAGE'::text            ELSE ''::text        END ||        CASE            WHEN "position"(split_part(split_part(','::text || array_to_string(pn.nspacl, ','::text), (','::text || role.name::text) || '='::text, 2), '/'::text, 1), 'C'::text) > 0 THEN ',CREATE'::text            ELSE ''::text        END, 2, 10000) AS privilege_type   FROM pg_namespace pn,    ( SELECT pg_roles.rolname AS name           FROM pg_roles        UNION ALL         SELECT ''::name AS name) role  WHERE replace((','::text || array_to_string(pn.nspacl, ','::text)),E'\"'::text,''::text) ~~ (('%,'::text || role.name::text) || '=%'::text) AND pn.nspowner > 1::oid;通过脚本可查询每个schema与用户权限的对应信息。示例
  • [POC&交付] Gauss DB(DWS)对接系列-数据可视化工具Grafana 7.4.3版本对接
    GaussDB Kernel提供自研的TSDB时序引擎,提供扩展的时序场景语法,以及分区管理、时序计算、时序生态函数等服务功能,此博文详细描述如何使用Grafana与DWS时序数仓对接,展示时序数据。1.DWS(时序数仓)构造测试数据Data Studio登录DWS(时序数仓)集群,创建用户、数据库及测试表--创建用户create user sxsc password 'Huawei@123';--创建数据库create database sxscdb owner sxsc encoding='utf-8' TEMPLATE template0;--赋予用户sxsc 模式public权限GRANT ALL PRIVILEGES ON SCHEMA public TO sxsc;执行结果如下:创建测试表,构造时序数据Data Studio上使用新建的sxsc用户登录sxscdb数据库创建测试表,并构造时序数据创建测试表:drop table if exists public.jiaocai;create  table if not exists jiaocai(type        text TSTag,devId      text  TSTag,PhV_phsA    double precision  TSField,PhV_phsB    double precision  TSField,PhV_phsC    double precision  TSField,PhV_neut    double precision  TSField,A_phsA      double precision  TSField,A_phsN      double precision  TSField,A_phsC      double precision  TSField,A_phsB      double precision  TSField,PhVAr_phsA  double precision  TSField,PhVAr_phsB  double precision  TSField,PhVAr_phsC  double precision  TSField,TotVAr      double precision  TSField,PhPF_phsA   double precision  TSField,PhPF_phsB   double precision  TSField,PhPF_phsC   double precision  TSField,TotPF       double precision  TSField,TotVA       double precision  TSField,PhW_phsA    double precision  TSField,PhW_phsB    double precision  TSField,PhW_phsC    double precision  TSField,TotW        double precision  TSField,PhVA_phsA   double precision  TSField,PhVA_phsB   double precision  TSField,PhVA_phsC   double precision  TSField,time        timestamp without time zone  TSTime)with (TTL='7 days', PERIOD = '1 day', orientation=TIMESERIES);COMMENT ON COLUMN public.jiaocai.PhVAr_phsA IS 'A相无功功率';COMMENT ON COLUMN public.jiaocai.PhVAr_phsB IS 'B相无功功率';COMMENT ON COLUMN public.jiaocai.PhVAr_phsC IS 'C相无功功率';COMMENT ON COLUMN public.jiaocai.TotVAr     IS '总无功功率';COMMENT ON COLUMN public.jiaocai.PhPF_phsA  IS 'A相功率因数';COMMENT ON COLUMN public.jiaocai.PhPF_phsB  IS 'B相功率因数';COMMENT ON COLUMN public.jiaocai.PhPF_phsC  IS 'C相功率因数';COMMENT ON COLUMN public.jiaocai.TotPF      IS '总功率因数';COMMENT ON COLUMN public.jiaocai.TotVA      IS '总视在功率';COMMENT ON COLUMN public.jiaocai.PhW_phsA   IS 'A相有功功率';COMMENT ON COLUMN public.jiaocai.PhW_phsB   IS 'B相有功功率';COMMENT ON COLUMN public.jiaocai.PhW_phsC   IS 'C相有功功率';COMMENT ON COLUMN public.jiaocai.TotW       IS '总有功功率';COMMENT ON COLUMN public.jiaocai.PhVA_phsA  IS 'A相视在功率';COMMENT ON COLUMN public.jiaocai.PhVA_phsB  IS 'B相视在功率';COMMENT ON COLUMN public.jiaocai.PhVA_phsC  IS 'C相视在功率';语法介绍:TSTag:维度属性字段TSField:指标属性字段TSTime:时间属性字段TTL:数据生命周期,此表数据生命周期为7天PERIOD:自动创建分区间隔,此表分区按照1天间隔创建Orientation:表属性,TIMESERIES说明是时间序列表创建存储过程insert_data(),模拟时序数据入库CREATE OR REPLACE PROCEDURE insert_data(v_number bigint)ASDECLARE  v_insert_jiaocai_string VARCHAR2(4000);  var_count               bigint;BEGIN  var_count               := 0;  v_insert_jiaocai_string :=             'insert into public.jiaocai(                                          type                                          ,devId                                          ,PhV_phsA                                          ,PhV_phsB                                          ,PhV_phsC                                          ,PhV_neut                                          ,A_phsA                                          ,A_phsN                                          ,A_phsC                                          ,A_phsB                                          ,PhVAr_phsA                                          ,PhVAr_phsB                                          ,PhVAr_phsC                                          ,TotVAr                                          ,PhPF_phsA                                          ,PhPF_phsB                                          ,PhPF_phsC                                          ,TotPF                                          ,TotVA                                          ,PhW_phsA                                          ,PhW_phsB                                          ,PhW_phsC                                          ,TotW                                          ,PhVA_phsA                                          ,PhVA_phsB                                          ,PhVA_phsC                                          ,time                                          )                                          values(                                          ''analog''                                          ,''025BHN6RK9522172_JC''                                          ,random()                                          ,random()*300                                          ,random()*300                                          ,random()*300                                          ,random()*300                                          ,random()*90                                          ,random()*300                                          ,random()*300                                          ,random()*60                                          ,random()*50                                          ,random()*40                                          ,random()*30                                          ,random()                                          ,random()                                          ,random()                                          ,random()                                          ,random()*20                                          ,random()*30                                          ,random()*40                                          ,random()*50                                          ,random()*60                                          ,random()*70                                          ,random()*80                                          ,random()*90                                          ,clock_timestamp() - interval ''7.815 hour''                                          );';  while var_count < v_number loop    EXECUTE IMMEDIATE v_insert_jiaocai_string;    var_count := var_count+1;    pg_sleep(5);    commit;  end loop;END;/ 执行存储过程,执行数据插入1000次,每5s插入一次call insert_data(1000);2.Grafana对接DWS时序数仓部署Grafana(windows版)Grafana下载地址:https://grafana.com/grafana/download?platform=windows下载完成后,在windows路径下解压文件grafana-7.4.3.windows-amd64.rar,如下图:进入bin目录双击grafana-server启动服务Grafana对接DWSGrafana登录地址:http://localhost:3000 默认用户名及密码:admin/admin,第一次登陆会提示修改密码Grafana中配置DWS数据源,点击Data Sources点击 Add data source选择PostgreSQL数据源配置DWS集群信息Save&Test保存Database Connection OK 说明连通性测试成功配置时序图标展示数据点击+Add new panel点击配置数据源,选择$DWS配置区配置要展示的时序数据,如下图:点击,可切换为SQL模式配置完成后点击apply应用此配置页面可以选择时序数据展示的时间区间及刷新频率
总条数:2065 到第
上滑加载中