• [技术干货] 数据仓库适用场景讲解------转载
    a) “数据同步模式” – 日志同步技术适用数据变化量小、数据传输压力小的数据场景,通常只适用于小型数据仓库平台;对于规模小的平台,RPO、RTO可以接近0;b) “数据同步模式” – 备份增量同步技术适合大数据量同步场景,实现方式容易被用户理解;往往需要数据库备份工具具备增量备份恢复能力;同时考验备份工具消除相关硬件限制条件,让该技术方案更加灵活;双集群的初始化同步往往采用全备全恢的逻辑实现,可以最大化、最快拉平存量数据;对于规模大的平台,RPO往往需要小时级别,RTO最好水准也在分钟、10分钟以上;同时主集群需要保障一定资源量供数据同步使用,对主集群开销大;c) “数据同步模式” – 逻辑数据同步技术适用灵活同步场景,往往数据同步量不会太大,或同步时间可容忍场景;此场景往往适合于用户对其数据仓库ETL过程元数据信息清晰、完整,依赖客户开发能力,相关同步数据存在清晰ETL算法,结合调度作业运行进度,动态发起相关数据表增、全量同步;对于中等规模的平台,RPO可以做到分钟、半小时,RTO可以维持在分钟级;d) “双ETL模式”需要两套ETL调度环境,整体成本翻倍,但调度逻辑清晰、易于理解和维护;较容易匹配不同规模的数据仓库平台采纳;较难实现数据实时比对,以及数据发生不一致之后的控制逻辑(若需要实现,对于调度逻辑侵入性大);ETL调度批量中途,较难实现两套调度链路协调重跑;同时数据不一致,依赖于”数据同步模式”技术辅助实施;由于主备调度进行不一致,无法做到主备统一视图展现;若双集群硬件相当,RPO、RTO均可以维持在分钟级别;e) ”双活模式“需要独立中间件、且严重依赖数据库自身厂商,中间件实现难度大;中间件的高可用(稳定性)成为它落地的最大障碍;“双ETL模式”的升级版,能适应各类数据仓库双集群场景;绝大部分场景下,RPO、RTO均可以接近0,特别是双活同时在线能力,不存在双集群的主备切换,RTO可以做到0;同时存在统一视图,不会因为其中一个集群故障,造成前后同一个查询返回结果不一致场景;
  • [技术干货] 数据仓库双活模式-----转载
    b) 双活功能点i.      访问路由能力客户端直接将中间件作为数据库登陆,保持原来登陆逻辑不变;中间件根据登陆用户及附加参数实现拒绝登陆、双系统登陆、或单系统登陆,实现写登陆、读登陆,实现受控方式登陆、或非受控方式登陆;即实现受控和非受控方式的系统读写;同时兼顾考虑异常路由选择或同步路由选择,满足最大化异常执行及少部分同步需求场景;ii.      SQL分发能力经中间件发送的SQL指令,正常发送到相应数据库,并接受数据库响应信息;iii.     批量导入、导出能力针对数据大批量的导入,需要考虑采用更加高效的加载协议进行数据加载,并考虑经中间件复制数据块,异步分发两个数据库;数据导出,需要考虑高效数据导出协议,从其中一套数据库正确导出数据;iv.     更新类SQL校验能力Delete、Update、Insert、Merge等更新类DML SQL进行SQL影响记录数校验;DDL/DCL执行返回码验证一致性能力;v.      对象注册功能通过路由及创建对象的DDL语句,实现对象动态注册;通过命令行指令实现对象注册;适当增加对象索引、约束索引的注册信息,用于扩展细粒度对象锁能力,提高数据仓库ETL SQL并发能力;*数据仓库环境下,只需要考虑到表级双活的能力,不建议实施字段级、记录级双活;vi.     对象锁能力根据SQL指令给相应对象动态加锁、释放锁;同时根据数据库自带的锁特征,至少区分读、写锁控制,以及部分数据库的脏读功能锁;vii.     对象状态控制能力进行管理的多套数据库在线状态控制;进行对象状态控制功能,包含不限于在线、离线、只读、只写、主动中断缓存中、被动中断缓存中、不可用等状态;viii.     缓存能力进行SQL指令流缓存能力,以及缓存恢复执行的能力;进行SQL与加载数据结合缓存、以及缓存恢复执行的能力;ix.      SQL异常控制能力考虑用户体验,始终由返回响应正确的SQL指令返回客户端;两个数据库返回均成功,但返回的影响记录数不一致,则响应慢的数据库对应SQL及涉及对象被设置成不可用状态;若两套数据库其中一套执行成功,另一套执行失败,则执行失败的数据库SQL和涉及对象被设置为被动中断缓存中,同时缓存SQL,定时重试SQL;若两套数据库返回均报错,才通知客户端报错;若SQL涉及对象已处理非在线状态,则新提交的SQL被缓存,新提交SQL相应对象被设置为被动中断缓存中。针对中间件和数据库之间,存在数据库已执行完、但中间件未收到信号场景,需考虑闪环该场景(如增加事务锁等);ü  主要通过Unity实现多集群SQL、数据分发与管理;ü  Data Mover实现集群间数据同步;ü  Eocsystem Manager实现数据批后自动校验及不一致重同步事件触发;ü  Viewpoint实现系统平台透视图展现与维护,并对接用户告警平台;d) 中间件高可用考虑由于引入了中间件(前置)服务,即该服务的稳定、可靠对双活模式至关重要。数据库单套系统本身已经具备极高的可用性,引入中间件后,由于所有数据库访问行为均通过该中间件,中间件任何异常均同时影响两套数据库访问能力。除了中间件本身所有相关服务需要满足高可用之外,还需考虑极端场景下bypass能力,此项能力在于极端异常条件下,可以保障系统持续服务的能力。高可用场景中,存在控制节点脑裂与自动升主场景,需借鉴仲裁机制减少脑残裂发生;e) 数据重同步考虑即利用“数据同步模式”相关同步技术,实现两套数据库数据重同步能力;f) 不确定值的SQL函数考虑最佳方案,是采用“数据同步模式”的数据日志重同步技术,直接将第一套数据库SQL执行结果的日志信息同步到第二套数据库中,消除返回结果不一致;部分简单的系统时间函数,直接通过中间件改写,保障SQL执行结果一致性;另外,则通过SQL改写,保证row_number函数进行主键或全字段排序,保证SQL执行结果一致性;g) 异常会话重放能力针对异常会话过程的SQL,可能需要从会话建立后,可视化选择,倒回前几个SQL重新执行,并指定过程SQL是否参与结果集校验,以及SQL回放结束的确认动作,让异常场景处理手段更加丰富。
  • [技术干货] 双ETL模式讲解------转载
    为保证两套ETL调度加载数据源一致及数据复用,往往要求搭建一个数据交换平台。因为至少存在一个文件被两套调度读取,要求数据交换平台两倍过往吞吐能力;且禁止加载的数据文件被二次覆盖,导致两套系统加载不一致; d) 调度依赖顺序考虑 由于ETL作业调度关系没有配置完备,即存在A作业使用B作业的数据,但不配置依赖关系(绝大部分的情况是A作业可容忍B数据的时效,是否最新数据均可以使用,故为时效,业务上不配置依赖关系;当然也存在物理时间上,通常B远远早于A执行),导致两套系统A作业生成数据不一致。该场景下,在一套调度平台无法发现此问题,但存在两套系统的校验比对,即发现数据不一致;该问题建议用户补全依赖关系,确认执行顺序一致性;当然若希望灵活使用依赖关系,则需二次开发,控制两套调度当日时序一致性;e) ETL代码服务器考虑 为了避免两套ETL调度代码维护不一致,需考虑统一维护渠道,包含不限于同一个代码存储源、版本服务器,以及代码变更时机f) 存在不确定值的SQL函数返回 ETL代码中往往存在sample、random、row_number排序这种同一份数据产生不同结果集的函数,造成两套系统数据不一致;该问题建议用户使用替代函数、明确取值、唯一排序,确保最终数据一致性;同时,该设计逻辑正确情况下,哪份数据均可被业务采信,若该数据对下游影响少,可每日批后从主库同步备库,拉平数据;g) 报错修数逻辑考虑 其中一套系统的数据发生报错、修数行为,会涉及到另一套系统的维护行为;可选作法是保留操作逻辑,待另一套系统发生报错时重复执行一次;其它交给数据质量校验(DQC)、数据校验去复查;h) 干预重跑修数逻辑考虑 若批后重跑,两套系统重跑逻辑一致,涉及重复劳动(或支撑平台优化),相对简单;但涉及批量过程中发现部分数据需要重跑,由于两套调度进度不一致,会导致i) 数据校验 i. 校验时机 批后校验,逻辑清晰,对调度依赖少,即根据整体调度进度,做到分层、分库或整体数据校验;准实时校验,即侵入调度环节,在每个作业完成时,均发起日志解析,提取每个SQL影响记录数,若相应作业SQL存在影响记录数不一致场景,即中止较晚完成的调度平台调度后续作业;ii. 校验手段 增全量校验,即针对不同加工逻辑的数据表,区分增、全量数据值,以最小代价覆盖所有业务表iii.   校验方法 通常作法有记录数、汇总值、checksum校验;汇总值校验,通过是数值型字段直接sum、字符型计算字符长度的sum、时间类型则转换成数值相加的比对;Checksum校验,针对全表或部分字段,进行md5或hash运算,完成两套系统一致性比对;对于关系型数据库,校验开销代价逐步递增(记录数 < 汇总值 < checksum校验);往往是结合增量校验、结合重要指标,区分维度校验,日常增量逻辑校验,定期全量校验,在校验数据一致性和系统性能之间取得平衡点。j) 优化考量 i. 校验改进 即嵌入调度平台,提取ETL代码运行日志,通过执行SQL影响的记录值,实时进行两套系统完成作业日志比对,发现记录值影响,立即停止备库调度,采用人工或自动方式修复数据,继续后续批量。该作法最大好处是,即时发现数据异常,避免问题放大,保障备库更高可用性;ii.   引入统一维护平台 即减少人为双系统维护操作,代码变更平台化,修数逻辑平台化,由平台分别下发两套调度平台、两套数据库。
  • [技术干货] 双集群系统方案探讨------转载
    当前社会、企业运行当中,大数据分析、数据仓库平台已逐渐成为生产、生活的重要地位,不再是一个附属的可有可无的分析系统,外部监控要求、企业内部服务,涌现大批要求7*24小时在线的应用,逐步出现不同等级要求的双集群系统。 数据仓库主流数据库平台均已存在多重高可靠保障措施设计,如硬盘冗余的raid设计、数据表冗余、节点备用冗余、机柜备用数据交叉等,以及加上服务进程高可用冗余设计,其最大化程度满足数据仓库服务持续在线。 但现实场景,如数据库软件缺陷、定期加固补丁、产品迭代、硬件升级这些产品现实因素,以及来自机房、数据中心、地域、网络的外部灾难故障因素,均在降低数据仓库可用性服务水平。 鉴于数据仓库存在大量数据吞吐,针对不同数据库、不同可用性要求,若需要设计双集群冗余设计,可选技术手段分别有数据同步模式、双ETL模式、双活模式,具体探讨如下: 由于数据库IO能力有限、且两个数据库间带宽有限,除了首次全量同步之后,后续通常考虑增量同步技术,即如何准确、高效获取“变化数据”,一般存在日志同步技术、备份增量同步技术、逻辑数据同步; b)日志同步技术 日志同步技术,有业内最著名Oracle Golden Gate,大部分厂家也有自己的实现方式,像Teradata近年来推出Unity CDM(变化数据广播)技术,而我司GaussDB for DWS可采用xlog及page进行变化数据同步。 优势:直接同步变化数据增量,数据量少,要求带宽低,但目前市面技术大都只适合数据每日变化量较少的数据仓库环境;劣势:现实的技术门槛高,应对各类异常场景适应能力差,对主数据库侵入性能要求高,一旦主库繁忙,同步时效低;面对全删全插等变化数据量大场景,同步吃力;c) 备份增量同步技术 主要利用各数据库平台备份恢复能力,进行数据增、全量备份、恢复;通常源库备份数据压缩之后,经网络传输后,解压恢复到目标库;对应GaussDB for DWS可采用roach备份恢复工具实现; 优势:利用同一技术实现增、全量数据同步,逻辑清晰,各场景容错能力强;劣势:要求数据库支持增备能力,且往往锁等待严重;d) 逻辑数据同步 该项主要涉及较高的业务侵入性,即充分获取ETL调度数据流元数据,对应数据库当日数据稳定之后,发起数据表导出-导入操作,针对数据表加工特性,选择增全量同步规则,进行数据准实时同步。 优势:较上述同步技术,可以实现多样选择性同步,同步过程由实施项目本身控制,做到表级数据同步,不需要全系统同步,即可实现部分业务双集群;劣势:客户化同步逻辑,操作前置依赖多,实施投入人力多,较难推广。
  • [技术干货] GaussDB(DWS)资源管控测试验证------转载
    (一) 测试SQL样例select count(1) from p#fasp_t_glctrl122299 a,p#fasp_t_glctrl122299   b;打印执行计划如下,cost值大于1000,已按方案设置资源管控的并发控制阈值cost为1000:(二) 交易用户并发验证使用交易用户budget_config_user使用测试SQL样例(cost值大于1000)启动100并发测试使用budget_config_user进行100并发样例SQL验证,当并发数达到50时管控,超过50并发后剩余SQL在管道内排队等待执行(三)报表用户并发验证使用报表用户report_user使用测试SQL样例(cost值大于1000)启动100并发测试使用report_user进行100并发样例SQL验证,当并发数达到20时管控,超过20并发后剩余SQL在管道内排队,等待执行。(四) 报表用户和交易用户同时并发验证分别使用交易用户budget_config_user和报表用户report_user使用测试SQL样例(cost值大于1000)分别启动100并发测试使用budget_config_user和report_user分别进行100并发样例SQL验证,交易用户并发50受控,报表用户并发20受控。(五)报表用户限额CPU验证使用报表用户report_user使用测试SQL样例(cost值大于1000)启动100并发测试CPU限额设置20%,使用report_user进行100并发样例SQL验证,CPU使用达到20%时进行资源管控。(六)交易用户配额CPU验证使用交易用户budget_config_user使用测试SQL样例(cost值大于1000)启动100并发测试在配额60%CPU的情况下,CPU使用可以超过60%,不进行CPU强制限制(这点与限额不同),业务高峰时可以根据业务情况弹性扩展。转载:https://mp.weixin.qq.com/s/VlT9u3JFYN4hwDnUofvH_A
  • [技术干货] GaussDB(DWS)资源管控方案规划------转载
    (一) 静态资源池规划静态资源池可以控制数据库能使用服务器资源的上限,由于服务器操作系统运行也需要消耗一定的资源,因此预留一定的服务器资源来保障操作系统的正常运行。推荐静态资源池配置:数据库分配93% CPU资源和70% 内存资源。这样可以保证服务器能够正常响应系统请求。静态资源池分配93% CPU资源和70% 内存资源。(二)交易用户和报表用户分离报表分析类业务的优先级和实时性相对较低,但是复杂度更高,为有效进行资源管控,将报表分析和核心交易业务进行数据库用户分离,例如核心交易业务使用数据库用户budget_config_user,报表分析业务使用数据库用户report_user。针对交易用户和报表用户分别进行CPU资源和并发数控制以保障数据库稳定运行。   结合报表分析业务的负载调研、日常监控和测试验证,20并发以内的复杂报表SQL不会引起服务器资源争抢,不会引起业务系统卡慢,因此配置报表用户最多使用20%的CPU资源。   结合核心交易业务的的负载调研、日常监控和测试验证,50并发以内的复杂SQL不会对系统造成持续压力,整体CPU负载小于60%。交易用户分配60%的CPU配额和50并发。报表用户分配20%的CPU限额和20并发。其中CPU配额是指占用CPU时间片的百分比。若分配给某个用户的CPU配额资源未使用,系统会自动将这些资源共享给其他用户。CPU限额是指用户可以使用的CPU核数的百分比。系统会将百分比换算成具体的核数供用户使用,且用户可使用的CPU限额资源不超过通过百分比换算的核数范围。(三)  并发管控阈值设置   资源管控的并发控制是基于SQL的cost值(SQL执行代价)来评估,结合客户场景、硬件配置和SQL测试分析,当SQL的cost值小于1000时,SQL并发对服务器不构成持续压力,短时间内可执行完成,不会造成业务堆积。当SQL的cost值大于1000时,大量并发会导致服务器资源争抢,引起系统卡慢。因此将受控SQL的cost的临界值设置为1000。当SQL的cost值大于1000时受资源管控的并发度控制,当SQL的cost值小于1000时不受资源管控的并发度控制。区分SQL复杂和简单的cost值设置为1000
  • [技术干货] GaussDB(DWS)资源管控方案技术场景分析------转载
    项目交付中可能会遇到同时包含核心交易(OLTP)和报表分析(OLAP)的混合业务场景,其中报表分析类业务复杂度高,消耗大量系统资源,但实时性要求较低,而核心交易类业务并发较大,多为简单事务处理,对实时性要求高。当系统处于业务高峰时,报表分析类业务并发操作会加剧系统负载,且长时间占用资源无法释放,最终可能导致整体性能裂化,实时性要求较高的核心交易类业务因资源争抢而无法得到响应,从而影响客户整体体验。资源管控的目的是基于业务场景和可用资源,进行合理的资源与并发度管控,以保障数据库可以在高负载场景下正常运行,不会因为资源争抢和耗尽出现系统卡死,提升系统整体吞吐量。业务场景主要分为核心交易(OLTP)和报表分析(OLAP)两大类,其中报表服务的优先级相对较低,在合理的情况下优先保障业务系统的正常运行。业务系统中运行的SQL分为简单SQL和复杂SQL,大量复杂SQL的并发执行会导致数据库服务器资源争抢,简单SQL的大量并发对服务器不构成持续压力,短时间内可执行完成,不会造成业务堆积。其中报表服务中运行的SQL以复杂SQL居多,整体业务逻辑相对复杂,在数据库层面需要分别对核心交易和报表服务进行合理的资源管控,以保障业务系统正常运行。
  • [技术干货] GaussDB(DWS)之冗余操作------转载
    通常情况下,会生成基表扫描的查询计划,即对于customer表的每一条,需要检查c_customer_sk列是否会和IN list中的某个值匹配,匹配即返回该条元组。当IN list中的条件比较多时,匹配近似于NestLoop的操作。针对这种场景,GaussDB(DWS)实现了In list to Join的查询优化规则,根据代价估算,针对In list中的值较多的场景,生成Hash Join的计划,极大提升性能,如下图所示:但代价估算存在估算不准的情况,对于列存表有min/max过滤,有时转成Join并不一定性能最好,因此我们增加了GUC参数:qrw_inlist2join_optmode,用户可以手动设置该参数的值进行调优,其值说明如下:a)   cost_base,即根据代价估算,默认值。b)   rule_base,强制使用转换成Join的优化规则。c)   不小于2的整数,表示当In list中的常量个数不小于N时,使用转换成Join的优化规则。在GaussDB(DWS)场景中,经常会遇到一类SQL,其中存在大量的冗余操作,导致执行时进行了大量无效计算。这类语句的场景很多,需要根据performance数据详细分析,以下举几个例子简单看一下。(1)语句中存在大量冗余case when语句的场景例如如下语句,语句中有大量case when语句,大多数条件都是一样的,只是default值存在不同,但执行时,每个分支的case when均需要执行,导致时间成倍增加。这种情况下需要对语句进行深入分析,根据语义进行等价改写。通常我们可以把case when加到过滤条件,分成多个子查询分别求值,或提取公共部分进行改写。经过优化后,消除了case when,性能得到了提升,修改后的语句如下所示。我们发现对所有的数据进行了排序,然后返回了前10条数据,数据量较大时,所有数据量全排将大量耗费时间。这种情况下,我们可以在子查询中加入limit语句,这样排序变为top N排序,减少了排序的时间,修改后的语句为:select a from (select a, row_number() over (order by a desc) rid from t1 limit <end>-<start>+1 offset <start>-1) where rid between 1 and 10;在GaussDB(DWS)场景中,通常为分析类应用,最终均需要进行聚集操作。通常聚集都是在语句最后进行,起到去重统计的效果。但是,如果去重前的重复值较多,但会显著影响关联的性能,如SQL语句:select t1.c1, count(*) from t1 join t2 on t1.c1=t2.c1 group by t1.c1;我们称这个改写规则为Eager Agg,相反,如果改写后的语句,在子查询中的Agg去重效果不明显,但耗时较长,则可以做反向改写,去除冗余的Agg操作,我们称之为Lazy Agg。转载:https://mp.weixin.qq.com/s/Jy27HVRIIuEXddrifXFlFw
  • [技术干货] GaussDB(DWS)之相关子查询场景------转载
    相关子查询,即子查询中需要依赖父查询的列值进行迭代计算的场景。例如如下语句:select (select ss_item_sk from store_sales where ss_item_sk<i_item_sk limit 1) from item;计划如下:在分布式框架下,为了保证每一行父查询元组均能够在子查询中迭代计算出结果,需要所有DN均维护一份子查询表的全局数据,在上面的计划中,子查询中的store_sales表进行了广播和物化,将数据存在所有DN上,见8层算子。第3层算子每一行数据均需要通过迭代子查询计算(第4层及之下的SubPlan 1)获得是否匹配的信息。这个计划执行非常慢且耗费资源,原因是:a)   在DN节点非常多的分布式环境下,将数据广播到所有DN上进行物化,将导致网络资源和IO资源耗费巨大,同时大数据量的广播耗时也很长。b)   对于父查询的每一行元组,均需要迭代计算子查询的值,类似于NestLoop的执行方式,效率极低。以上两个问题带来的语句性能问题在各个客户现场均被识别,因此需要进行通用子链接提升转成join的查询重写来解决该问题。在之前的版本中,我们已经支持了如下场景的子链接提升,即将子链接转化为join获得性能提升,这些子链接均出现在where条件里,包括:a)    IN/NOT IN的非相关子查询。b)   EXISTS/NOT EXISTS的等值相关子查询。c)    包含Agg表达式的等值相关子查询。d)   以上场景子查询的OR场景。当然,目前我们还不支持目标列上出现相关子查询的场景,以及相关子查询中出现不等值比较的场景,需要首先识别出坏味道,进行语义等价的整改。转载:https://mp.weixin.qq.com/s/Jy27HVRIIuEXddrifXFlFw
  • [技术干货] GaussDB(DWS)之全局性操作------转载
    GaussDB(DWS)分布式数据库的优势,就是利用多DN的资源进行并行计算,提高吞吐量。但有些SQL在这些方面不够注意,导致执行过程中由于全局性操作仅能在一个DN或CN上执行,造成了性能瓶颈。不能下推即属于这一类型问题。除了不能下推,本章节主要讨论在DN上进行全局操作导致的问题。客户场景遇到的主要问题,是需要对全量大数据量进行排序的问题,比如:windowagg函数没有partition by,但包含order by的问题。例如如下语句:select * from (select ss_sold_date_sk, sum(ss_sales_price) over  (order by ss_sold_date_sk rows 2 preceding)  sum_2, sum(ss_sales_price) over (order by ss_sold_date_sk rows 5 preceding) sum_5 from store_sales), date_dim where ss_sold_date_sk=d_date_sk and d_year=2000 and d_moy=5 order by 1;计划中第4层将所有DN的数据广播到一个DN上进行全局排序,并计算sum窗口函数的值,导致性能瓶颈。对于类似情况,在语义允许的情况下,尽量给窗口函数增加partition by的字段,这样分组计算时,GaussDB(DWS)可以将计算分配到不同的DN上进行,提高执行效率。NestLoop是最简单的表关联手段,当然也是最低效的,每条元组之间都要进行匹配,数据量大的时候经常执行不出来。所以在GaussDB(DWS)中,我们经常使用HashJoin进行表的关联。但有些SQL语句从语义上决定,只能使用NestLoop的方式执行,导致性能问题。总结起来,有以下几方面:在GaussDB(DWS)中,我们推荐使用等值关联,这样可以使用HashJoin进行执行加速。但对于非等值关联条件,只能使用NestLoop的方式进行连接,同时需要将其中一个表进行Broadcast广播到所有DN进行。如果两个表都比较大,将导致性能瓶颈。例如如下:select * from t1 join t2 on t1.a<t2.a;类似的场景还有:<1> select * from t1 join t2 on 1=1;这个语句无关联条件,我们称为笛卡尔积关联,返回结果行数为t1和t2行数的乘积。<2> select * from t1 join t2 on t1.a=t2.a and t1.a=5;这个语句虽然有等值关联条件,但关联条件还有个过滤条件t1.a=5,所以实际上t1.a=t2.a=5,是在a=5过滤基础上的笛卡尔积。这类语句都会导致性能瓶颈。转载:https://mp.weixin.qq.com/s/Jy27HVRIIuEXddrifXFlFw
  • [技术干货] GaussDB(DWS)之数据类型转换------转载
    数据库在进行不同列的比较、计算运算时,如果类型不同,需要进行类型转换。通常情况下,由优化先低的类型往优先级高的类型转换,字符串的优先级较数字较低,同时数字类型,精度低的会向精度高的转换。在应用中,经常遇到的是,字符串和数字进行比较,导致字符串需要转成数字进行比较操作。由于数据库的基本调优都是基于基表列的,数据转换后就会带来以下性能问题:(1)无法使用索引。由于索引是基于列的排序构造的,字符串转换成数字后的排序性与字符串不一致(’2’与’12’,字符串’2’大,数字12大),故无法使用索引,对于返回数据量少的场景,使用全表扫描带来性能问题。(2)无法进行分区剪枝。GaussDB(DWS)支持range分区,即根据分区键值的范围创建不同的分区。当需要进行分区键上的范围操作时,进行分区剪枝。而字符串转换成数字后,道理与(1)类似,打破排序性,导致分区剪枝失效。(3)需要进行网络重分布操作。在进行表的关联,聚集操作时,如果涉及表分布键的操作,可以在本地并行进行。但如果涉及到类型转换,则hash值发生变化,需要进行网络重分布,增加了网络开销。(4)估算不够准确,可能造成计划的性能问题。我们收集的统计信息都是基于基表列的,如果进行类型转换,则缺少转换后的统计信息,同样可能造成计划不准。因此,在表设计之初就要把数据类型定义好,数字类型尽量使用整型或numeric(浮点型),尽量少使用字符串数据类型,除了与数字比较产生上述开销外,变长的字符串在处理时还产生了额外的空间申请释放,内存拷贝的开销,都是无形中性能的损耗。在share-nothing架构的分布式场景下,数据使用哈希分布在不同DN上,并且通过数据重分布使得中间结果均匀分布在各个DN上进行并行计算,进行执行查询的加速。所以在执行过程中,一直保持数据能够均匀分布在DN上,是保证性能的关键。通常情况下,我们需要进行表的关联(Join)和聚集(Agg)操作,这就需要关联和聚集列能够支持重分布,从而进行灵活的重分布操作。在GaussDB(DWS)中,不支持重分布的类型主要有real和double类型,因此使用这两种类型进行操作时,将导致无法生成重分布的计划,在实际使用时要尽量避免。首先,在进行表定义时,要尽量避免使用这两种类型,使用numeric类型进行替代。同时,还要避免使用返回值为这两种类型的函数,进行关联和聚集运算,例如:ceil, floor, pow, sqrt, 以及一些分析类聚集函数如stddev_samp等。如果必须使用此类函数进行相关运算,需要在计算完对这些类型进行类型转换,转换成numeric类型。转载:https://mp.weixin.qq.com/s/Jy27HVRIIuEXddrifXFlFw
  • [问题求助] springboot使用mybatis-plus连接openGauss-5.0.1,between查询报错
    springboot使用mybatis-plus连接openGauss-5.0.1,使用between查询时报错,请各位大神帮忙排查!!!报错信息如下: jdbc.sqltiming                           : 6. PreparedStatement.execute() FAILED! SELECT DATE_FORMAT(alarm_time, '%Y-%m-%d 00:00:00') AS time, alarm_level as alarmLevel, IFNULL(COUNT(*),0)  AS count FROM monitor_alarm WHERE (alarm_level IN ('1','2','3','4','5') AND alarm_time BETWEEN  '2024-04-10 17:06:45' AND '2024-04-17 17:06:45') GROUP BY DATE_FORMAT(alarm_time, '%Y-%m-%d  00:00:00'), alarm_level   {FAILED after 58 msec}  org.postgresql.util.PSQLException: [************:5432] ERROR: could not determine data type of parameter $6     at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2922)     at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2643)     at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:375)     at org.postgresql.jdbc.PgStatement.runQueryExecutor(PgStatement.java:561)     at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:538)     at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:396)     at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:166)     at org.postgresql.jdbc.PgPreparedStatement.execute(PgPreparedStatement.java:155)     at net.sf.log4jdbc.PreparedStatementSpy.execute(PreparedStatementSpy.java:417)     at com.alibaba.druid.pool.DruidPooledPreparedStatement.execute(DruidPooledPreparedStatement.java:497)     at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)     at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:79)     at sun.reflect.GeneratedMethodAccessor142.invoke(Unknown Source)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:498)     at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:63)     at com.sun.proxy.$Proxy96.query(Unknown Source)     at com.baomidou.mybatisplus.core.executor.MybatisSimpleExecutor.doQuery(MybatisSimpleExecutor.java:69)     at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:325)     at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)     at com.baomidou.mybatisplus.core.executor.MybatisCachingExecutor.query(MybatisCachingExecutor.java:165)     at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:81)     at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)     at com.sun.proxy.$Proxy95.query(Unknown Source)     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)     at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)     at sun.reflect.GeneratedMethodAccessor212.invoke(Unknown Source)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:498)     at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)     at com.sun.proxy.$Proxy92.selectList(Unknown Source)     at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)     at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:173)     at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:78)     at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)     at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)     at com.sun.proxy.$Proxy166.selectMaps(Unknown Source)     at cn.hite.monitor.alarm.manager.RemoteClientAlarmManager.alarmList(RemoteClientAlarmManager.java:65)     at cn.hite.monitor.alarm.controller.AlarmController.alarmList(AlarmController.java:179)     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)     at java.lang.reflect.Method.invoke(Method.java:498)     at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105)     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:878)     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:792)     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:645)     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)     at javax.servlet.http.HttpServlet.service(HttpServlet.java:750)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)     at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)     at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)     at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)     at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)     at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)     at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)     at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)     at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)     at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)     at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:450)     at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)     at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)     at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)     at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)     at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)     at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)     at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)     at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)     at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893)     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707)     at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)     at java.lang.Thread.run(Thread.java:750) 
  • [运维管理] 集群WEB管理控制台HTTPS界面,如何不提示证书无效(NET::ERR_CERT_AUTHORITY_INVALID)
    我们现在有一个自动打开集群控制台的程序(https://xxx.xxx.xxx.xxx:28443/web)但是每天次打开都出现这个证书无效的界面,如下图所示,目前没有办法识别这个界面,所以有没有什么办法 不显示这个界面,打开网址就直到输入用户名和密码的界面,比如,向浏览器中导入根书,但我又没有证书。
  • [用户实践] 上周末D-SMART高斯生态版
    上周末我们就会封板D-SMART高斯生态版了,这个版本是基于D-SMART V2.6基础版开发的,不过与惯例不同的是,我们这回会先发D-SMART高斯生态版,两周后再发标准版V2.6。在V2.6版本中有两个十分重要的新增功能,其中第一个是图形化的集群拓扑,这个功能是专门为Gaussdb开发的,为了支持其他D-SMART能纳管的数据库,我们还需要做一些改造工作。随着D-SMART对国产数据库的支持越来越多,集群拓扑的重要性也越来越高,无论是分布式数据库还是集中式数据库,在用户的生产环境中大多数都会以集群方式部署。老的字符界面的集群拓扑对专家友好,但是对普通运维人员来说看起来不够直观。 在集群拓扑上,你还可以点击某个CN/DN节点,进行下钻分析。对于Gaussdb来说,集群和CN/DN是独立的运维对象,你既可以对集群的健康状态进行分析,也可以对某个节点进行单独分析。节点的数据库类型是不同的,类似一个独立的集中式数据库。第二个比较重大的改进是支持了一种新的泛化分析工具-基于运维原理的指标集分析工具,这个工具就是昨天我说的写三行代码的工具。对于智能化运维工具来说,强大的智能的背后都是巨大的人工。要想让系统有更强的自动化分析能力,需要大量的能够针对某个具体的问题进行分析诊断与定位的工具。基于D-SMART的基础能力,如果我们的某个问题的分析定位可以通过某几个指标来完成,那么我们只需要写三行代码就可以完成一个分析工具的开发工作。          上面几行代码的实际执行效果如上图,对于某些能够梳理出来的问题分析场景,其分析结果对于稍微有经验的运维人员来说还是比较容易理解的。这个工具比泛路由工具更为精准,与泛路由工具结合,可以获得更好的效果。 上面是针对同一个故障告警,利用泛路由工具的分析结论。在需要更泛化的分析辅助的时候,使用泛路由工具更加有效,而对于已经比较明确的问题的定位,新的工具效果更佳。目前这个功能仅对商用版提供,还没有开放到社区版中。高斯生态版支持的运维对象类型为OS/GaussDB和高斯生态产品。高斯生态产品包含了GaussDB的CN/DN节点以及openGauss与相关生态的商用产品。目前我们已经适配了openGauss 2.x-5.x,实际上新的6.0也是没问题的。除此之外,我们已经完成了与南大通用GBASE 8C、海量、恩墨MogDB等数据库的适配工作。其他高斯生态的数据库厂商如果需要适配,可以和社区联系,我们会尽快纳入。对于Gaussdb我们将支持轻量化部署的线下版,也将支持云环境的版本(公有云和私有云),我们随后将会和华为生态部门调试云上的采集接口。高斯生态版的默认首页也采用了全新的贴片界面,对于集群数据库而言,在贴片首页上我们可以只显示集群对象,而CN/DN节点被隐藏在后面,可以通过集群拓扑界面进入。不过这些对象的告警还是会被推送到首页和告警短信等位置。从上面的告警我们可以看到在首页中没有看到的DN/CN节点的告警信息。          在功能上,高斯生态版延续了几乎所有的标准版的功能,同时也提供HOLA工具,让用户可以下载监控数据,交给远程专家导入到一个D-SMART中进行离线分析,或者进行远程巡检等工作。本周我们将完成高斯生态版的封板工作,届时会在DBAIOPS社区发布下载的链接,对于正在使用Gaussdb或者相关生态数据库产品的朋友,欢迎下载并申请使用。我们也将会在一个月内为申请的朋友免费赠送终身使用许可证。一个数据库运维工具必须在用户的真实环境中使用才能逐步完善,也希望朋友们帮我们完善这个产品。    
  • [问题求助] DWS 8.1.1.5版本,CStoreCUCacheSweepLock 用于列存CU Cache循环淘汰。这个的实现原理是什么?
    DWS 8.1.1.5版本,CStoreCUCacheSweepLock 用于列存CU Cache循环淘汰。这个的实现原理是什么?只有vacuum full 或vacuum full analyze的时候会触发吗?
总条数:1672 到第 页
上滑加载中