• [技术干货] 索引基本原则
    索引可以用来提高数据库查询性能,但是不恰当的使用将导致数据库性能下降。建议仅在匹配如下某条原则时创建索引。 经常作为where子句的过滤条件上的字段; 经常作为连接条件的字段,对于存在多字段连接的查询,建议在这些字段上建立组合索引; 例如, select * from t1 join t2 on t1.a=t2.a and t1.b=t2.b,可以在t1表上的a,b字段上建立组合索引。 经常出现在order by、 group by后的字段; 经常作为查询返回结果的字段,distinct、max后的字段; 创建组合索引时,区分度高(DISTINCT值多)的列放前面。 分析过程: 1) 每5min从上游同步一次数据 -> 高频实时入库场景,推荐使用行存表; 2) 表数据量10亿 -> 数据量较大,评估该表查询模型,是否涉及多表关联的分析型查询; 3) 查询性能要求高,涉及多表关联分析型查询 -> 需要列存提升性能。
  • [技术干货] 索引设计最佳实践
    索引之利 :提供主键和唯一性约束,满足业务需要 索引之弊 :索引页面占用额外空间,导致一定的磁盘膨胀 点查询提速显著,直接定位到需要的数据,减少无效IO 利用等值条件索引查询速度快的优势,结合nestloop提高多表join效率 影响数据增删改的性能,因都涉及索引更新操作 索引需要记录XLOG,更新索引会增加主备同步压力 利用索引天然有序的特质,加速排序、求max等操作性能 当统计信息收集不及时触发优化器误判选到不该选的索引计划,可能导致查询性能反向劣化 利用倒排索引加速全文检索 分区表上每个分区都有各自的索引,分区和索引过多会增加cache memory等公共资源的消耗btree 行存默认索引类型(列存也支持),适用于主键、点查场景 相比psort,无论是点查还是范围查询,性能均更优;略微不足的是磁盘空间的占用及对导入性能的影响比psort稍差。 psort 列存默认索引类型,适用于范围查询场景 性能提升效果比较中庸,在列存支持btree后,建议直接用btree索引 注意:列存表上创建索引不指定类型时默认是psort,所以建议在列存上创建索引时显示指定索引类型为btree。 通用倒排索引,适用于全文检索场景 特定场景使用 通用搜索树索引,适用于位置检索场景 特定场景使用
  • [技术干货] 分区选择策略
    分区相当于把逻辑上的一张表根据分区键划分成几张小表进行分别存储,建议大表都考虑做分区,其好处主要有: 1) 改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索效率; 2) 增强可用性:如果分区表的某个分区出现故障,表在其他分区的数据仍然可用; 3) 方便维护:定期删除数据的场景,可只针对特定分区做TRUNCATE PARTITION和DROP PARTITION,效率高且不产生脏数据,维护成本低。 (RangePartitioning) 根据分区键值的范围,将数据存储到不同的分区中,分区键范围连续但不重叠。 1、日期或者时间类的字段作为分区键 2、查询中大多包含分区键作为过滤条件 3、定期按照分区键清理数据 列表分区(ListPartitioning) 根据分区键值的列表进行分区,各分区的列表值不重复 1、特定数量的枚举值作为分区键值 2、查询中大多包含分区键作为过滤条件 
  • [技术干货] 分布方式选择策略
    分布方式主要决定了数据的存储分布情况,同时也直接影响后续关联查询的计算效率。Hash:表数据按照分布列生成的hash值与 DN实例的映射关系,将数据分布到各DN实例。 优点:每个DN仅包含部分数据,占用整体空间小。 大表、事实表。 缺点:数据分布的均匀程度强依赖分布列的选择;JOIN关联条件不包含各自分布列的场景存在节点间数据通信的消耗。 RoundRobin 表数据按照轮询的方式依次分布到各DN实例。 优点:每个DN仅包含部分数据,占用整体空间小;数据轮询均匀分布,不依赖分布列,不存在数据存储倾斜问题。 缺点:无法通过分布列条件消除和减少节点间通信,此类场景性能不如Hash分布方式。 Replication 表中的全量数据在集群的每一个DN实例上保留一份。 优点:每个DN上都有此表的全量数据,JOIN操作中可以完全避免节点间数据通信,从而减小网络开销,同时减少了STREAM线程启停开销; 大表、事实表,无合适分布列的表。 
  • [技术干货] 表设计最佳实践
    表是数据库中最基础的对象,其设计的好坏直接决定后续业务的稳定性。表设计的关键在于存储方式、分布方式、分区策略的选择,这些选择均和业务特征强相关,要结合业务实际特征来设计。 当前表的主要存储类型即行存和列存,存储方式和业务特征决定了数据占用的空间、膨胀的速度、查询性能的优劣和稳定。 DML增删改:UPDATE和DELETE操作多的场景。 DML查询:点查询(返回记录少,基于索引的简单查询)。 DML查询:统计分析类查询(group , join的数据量大的场景)。 DML增删改:INSERT批量导入场景(单次单分区入库量接近或大于6w* DN数)。 DML查询:统计分析类查询(group , join的数据量大的场景)。 DML增删改:UPDATE/DELETE多的场景、INSERT小批量插入的场景DML查询:高并发的点查询
  • [技术干货] 连接池规范
    如果用户在APP的开发中,使用了连接池机制,那么需要遵循如下规范: 如果使用连接池,需要确保应用侧连接池的空闲超时时间配置要不长于DWS中,SESSION_TIMEOUT时间,或者连接池中连接建连后设置关闭SESSION_TIMEOUT,否则可能导致业务从连接池获取的连接已在DWS中超时退出,从而出现报错。 如果使用连接池中的连接并设置了GUC参数,那么在将连接归还连接池之前,必须使用“SET SESSION AUTHORIZATION DEFAULT;RESET ALL;”将连接的状态清空,否则连接被其他业务复用时,可能会出现性能、业务报错等各类问题。 如果使用连接池中的连接创建了临时表,那么在将连接归还连接池之前,必须手动删除临时表,否则连接被其他业务复用时,可能出现临时表创建报错问题(临时表为 session 级别对象,使用同一个连接池连接,相当于在同一个session,临时对象也不能重名)。 应用侧有使用连接池的场景,如果在DWS侧通过GS_GUC RELOAD设置了全局的GUC参数,需要重启应用侧连接池才能够享受该参数变化,因该设置只针对新建的连接生效,针对连接池中已有的老连接不生效。 在应用中的复杂作业和简单作业场景,建议单独划分连接池,避免作业间公共资源消耗的影响(如IDLE连接内存消耗)。 在应用侧连接数不受控的场景,可以借助连接池机制控制应用侧接入的的活跃会话数。
  • [技术干货] 通用连接规范
    保证业务连接均匀分布到各CN,参考29.1.3配置负载均衡,避免单CN出现并发瓶颈; 应用程序使用连接完成作业任务之后,需及时主动CLOSED连接,避免IDLE空闲连接持续占位增长,导致无法新建连接; 应用程序尽量使用自动提交方式(默认autocommit),如需关闭 autocommi时则需应用程序确保事务手动提交,避免造成大量“idle in transaction”的连接; 引用通过JDBC连接数据库时,应该保证下面三个时区设置一致: a) JDBC客户端所在主机的时区。 b) GaussDB(DWS) Server所在主机的时区。 c) GaussDB(DWS)集群配置中时区(例如:SET TIME ZONE 'UTC-8')。规划数据库用户是规划整个业务模型的一部分,建议根据各业务模块进行用户划分,合理的用户划分能够帮助DBA从服务侧更有效的区分业务优先级,以及不同业务类型的精确管控,同时便于做更精确的资源管控。
  • [问题求助] cm_ctl、gs_ctl、gs_om的关系
    cm_ctl、gs_ctl、gs_om好像都可以管理集群,有什么区别啊,用哪个更好呀
  • [技术干货] 【技术总结】华为云GaussDB与PostgreSQL区别10条总结
    以下是华为云GaussDB与PostgreSQL(pgsql)不一样的10个关键点总结:内核架构与模型GaussDB将PostgreSQL的进程模型改为线程池模型,降低了内存溢出风险,但牺牲了操作系统级进程终止的灵活性(如无法使用kill命令直接终止连接)。事务ID位数PostgreSQL使用32位事务ID,高并发场景下易耗尽(约12小时需执行VACUUM FREEZE);GaussDB升级为64位事务ID,彻底解决该问题,支持无限事务处理。全局事务管理(GTM)GaussDB引入第三方etcd集群存储全局事务号,将GTM工作剥离,实现高可用强一致;PostgreSQL依赖GTM单节点或主备架构,存在性能瓶颈和单点故障风险。存储引擎多样性PostgreSQL仅支持行存储;GaussDB支持行存、列存及Ustore(混合存储),适应不同场景需求(如分析型查询用列存,事务型用行存)。分布式架构能力PostgreSQL原生支持单节点,需通过插件(如Citus)实现分布式;GaussDB企业版原生支持分布式架构,数据自动分片,支持跨地域集群部署。高可用与容灾PostgreSQL高可用依赖主备切换和第三方工具;GaussDB提供集群管理模块(CMS),支持故障自动切换、进程自愈,且主备切换后原主库可自动重建。并行查询优化PostgreSQL支持并行查询,但需手动配置;GaussDB在分布式架构下优化多节点并行查询,显著提升复杂查询性能。安全特性增强PostgreSQL提供基础安全机制(如SSL加密、行级访问控制);GaussDB增加数据动态脱敏、全密态计算、防篡改等企业级安全特性,符合国密标准。跨版本与模式兼容PostgreSQL为单一数据库;GaussDB支持多模式(如Oracle兼容模式、MySQL兼容模式),便于异构数据库迁移,降低企业替换成本。商业支持与生态PostgreSQL依赖开源社区支持;GaussDB由华为提供企业级商业支持,包括定制化服务、性能调优、专属工具(如DRS数据迁移服务),适合大规模企业应用。
  • [问题求助] gs_dump备份
    我想请问大佬,gs_dump备份可以对于一张表指定条件吗,我现在有一张300个分区的表,其实我只需要备份其中的15个分区,其余不需要备份
  • [问题求助] GaussDB xlog追平速度
    我想请问大佬,对于一张200G的大表,Drop它的xlog追平速度和Truncate它的xlog追平速度差别大吗,哪个快呢
  • [问题求助] tpops订购容量后怎么注销,重新申请
    如图所示,tpops已经订购容量了,但是现在想改成每主机的方式后重新申请。怎么做
  • [运维管理] GaussDB 运维案例集
    目  录1 DN动态内存使用满导致DN主备切换2 iptables策略限制导致实例升级报错3 修改bashrc导致om-agent升级失败4 目录权限问题导致DN异常5 2025-115.1 业务SQL包含自定义function,通过hint方式添加query_dop,smp不生效5.2 JDBC导入和gsql导入在insert,replace,duplicate方式性能差异5.3 主备切换时间长问题分析5.4 主机流控导致大量业务超时并且无法新建连接5.5 业务分布键选择不合理导致数据分布不均匀5.6 DN发生主备切换问题定位 1、DN动态内存使用满导致DN主备切换故障现象客户反馈,在05:00--10:31之间GaussDB集中式在DN主备切换。适用版本GaussDB全部版本。告警DN主备切换。业务影响业务闪断,1min内恢复。故障原因l   主备切换问题,通常先找到主备切换的节点,即原主DN,新主DN分别是哪个DN。l   然后先从cm_server主、cm_ctl等日志分析,确认主备切换的命令是由cm_server下发还是手动下发。l   最后如果是cm_server下发主备切换的命令,通常是原主DN异常,则分析原主DN 异常原因。处理办法                                步骤 1     确认DN主备切换时间点。查看cm_server主日志,搜索关键词“Failover message has sent to instance”,从日志中发现,2024-04-23 05:02:34,cm_server下发命令,将dn_6002切换为主DN。cd $GAUSSLOG/cm/cm_servervim cm_server-yyyy-mm-dd_******-current.log继续查看cm_server主日志,搜索关键词“send switchover to instance”,发现在2024-04-23 10:31:21,手工下发了switchover命令,将dn_6001切换为主。经以上分析,2024-04-23 05:02:34因为dn_6001的某些故障,cm_server将主DN切换为dn_6002,2024-04-23 10:31:21手动下发switchover命令将dn_6001切换为主。                                步骤 2     定位发生主备切换原因。查看DN进程,发现进程在05:02发生重启。ps ux|grep dn                                步骤 3     查看是否生成ffic日志。进入日志目录,发现存在ffic日志。cd $GAUSSLOG/ffic_log                                步骤 4     分析ffic日志。查看ffic_log日志,发现dn_6001因为发生oom,被AI Watchdog杀掉进程,从而触发主备切换。                                步骤 5     查看dn_6001日志。搜索关键词,AI Watchdog,发现是因为动态内存上涨,触发AI Watchdog主备切换。cd $GAUSSLOG/pg_log/dn_6001vim postgresql-yyyy-mm-dd_******.log                                步骤 6     查看动态内存使用情况。查看监控指标,动态内存使用率瞬间冲高。                                步骤 7     查看dn_6001动态内存上下文根。发现hashBatchContext上下文根动态内存使用高,判断可能为大的查询,其中的hash关联占用动态内存高。cd $GAUSSLOG/mem_log/dn_6001_6002_6003                                步骤 8     查找动态内存占用高的SQL语句。发现占用动态内存高的SQL语句为insert into语句,该语句存在大量的关联查询,在执行该语句时发生申请内存失败,报错信息为:memory is temporarily unavailable。cd $GAUSSLOG/pg_log/dn_6001zgrep -i debug_query_id postgresql-yyyy-mm-dd_******.log.zg | awk -F 'consuming about' '{print $2}'|sort -nk1                                步骤 9     优化insert into语句。----结束2、iptables策略限制导致实例升级报错故障现象客户进行实例升级,任务流报错,升级失败,如下图所示。适用版本GaussDB全部版本。业务影响l   管控任务流报错,无影响。l   内核任务流报错,自动回滚成功,无业务影响,运维功能、备份可能会受影响。l   内核任务流报错,自动回滚失败,集群状态可能异常,影响业务。故障原因根据报错任务流时间,147秒报错,说明升级任务流可能还没有下发内核,可能在om_agent前置校验阶段报错。处理方法                                步骤 1     根据升级报错任务流,找到命令下发节点。如下图,单击“操作 > 修改context”,找到“NODE_ID”。                                步骤 2     根据NODE_ID,找到对应节点,登录到节点后台。                                步骤 3     切换到Ruby用户,加载环境变量,执行如下命令,查看升级日志。ll $GAUSSLOG/om/gs_upgradectl_2025*.log                                步骤 4     发现节点上没有产生内核升级日志,说明升级动作还没有到内核侧,返回查看om_agent的日志。                                步骤 5     执行如下命令,查看om_agent的升级日志。vim /home/Ruby/log/om_agent/agent.log                                 步骤 6     搜索报错时间点前后有没有“ERROR、failed”等报错信息。                                步骤 7     根据报错日志分析,检查数据库连接失败:Check database connection failed。根据报错日志“could not connect to server: Operation now in progress Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 8000”分析,怀疑是gsql连接数据库报错。                                步骤 8     在数据库节点执行如上命令,指定-h 127.0.0.1不通,不指定可以连上,怀疑是127.0.0.1不通。l   指定-h 127.0.0.1l   不指定-h 127.0.0.1                                步骤 9     执行如下命令,测试127.0.0.1的连通性,连接失败。curl -kv 127.0.0.1 8000                             步骤 10     通过如下命令检查数据库连通性,是,指定-h 127.0.0.1。gsql -d postgres -p $port -h 127.0.0.1 -U rdsAdmin -W $password -m -c 'select 1;'                             步骤 11     127.0.0.1不通,怀疑是设置了iptable策略,root用户下执行如下命令查看iptable策略。iptables -L                              步骤 12     如上图,iptables策略存在一条策略限制了127.0.0.1访问。                             步骤 13     执行如下命令删除限制127.0.0.1的策略。iptables -D INPUT -p all -s 127.0.0.1/24  -j REJECT                              步骤 14     执行如下命令,测试127.0.0.1的连通性,连接成功。curl -kv 127.0.0.1 8000                             步骤 15     通过gsql连接,也可以连接成功。                             步骤 16     管控界面重试任务流,升级成功。----结束3、修改bashrc导致om-agent升级失败故障现象通过TPOPS平台,升级GaussDB实例,升级报错,查看升级任务流,升级子任务om-agent失败。适用版本GaussDB全部版本。业务影响升级失败。故障原因实例节点上,/home/Ruby/.bashrc 该文件为环境配置文件,该文件在实例安装成功后手动添加了 source ~/gauss_env_file 环境变量 ,导致升级om_agent时,自动加载了GAUSSHOME,使其获取到了GAUSSHOME/bin目录下的openssl,正常要求使用操作系统自带的openssl来生成客户端和服务端的证书和私钥。因为环境变量加载的的openssl路径不对,所以报错证书和私钥不匹配,无法正常启动om_agent进程,导致升级失败。处理办法                                步骤 1     查看om_agent日志,提示om_agent拉起失败。                                步骤 2     通过 ps -ux 查看 om_agent 进程是否拉起,未拉起,手动尝试拉起om_agent, 提示ssl证书相关错误。                                步骤 3     查看.bashrc 环境变量,发现手动添加了 source ~/gauss_env_file。                                步骤 4     登录实例每个节点,去掉 .bashrc 中手动添加的环境变量 source \~/gauss_env_file ,然后重做任务流。----结束4、目录权限问题导致DN异常故障现象复现案例:集群升级完后一个DN状态为down。cm_ctl query -Cv适用版本GaussDB全部版本。业务影响所有CN/DN权限异常,会导致数据库无法正常启动。故障原因升级过程中需要重启DN,DN数据目录由于权限问题无法正常启动。处理办法                                步骤 1     查看DN异常节点om_agent、cm_agent、cm_server等守护进程无异常。ps ux                                步骤 2     查看cm_agent进程日志打印有拉起动作但是未正常拉起,排除CMA异常。cd $GAUSSLOG/cm/cm_agent vim cm_agent-*current.log StartAndStop ASYN LOG: BuildStartCommand 0 StartAndStop ASYN LOG: DN START system(command:/usr/local/core/app/bin/gaussdb    -D /var/lib/engine/data1/data/dn_6002 -M pending >> "/var/lib/engine/data1/log/Ruby/cm/cm_agent/system_call-current.log" 2>&1 &), try 4 StartAndStop ASYN LOG: the dn(id:6002) instance restarts counts: 66 in 10 min, 66 in hour. DnStatus6002 ASYN ERROR: [get_connection: 1446]: fail to read pid file (/var/lib/engine/data1/data/dn_6002/postmaster.pid). DnStatus6002 ASYN ERROR: failed to connect to datanode:/var/lib/engine/data1/data/dn_6002 DnStatus6002 ASYN ERROR: DatanodeStatusCheck failed, ret=-1 DnStatus6002 ASYN LOG: set 6002 on offline. CheckProcess ASYN LOG: process (gaussdb) is not running, path is [[/var/lib/engine/data1/data/dn_6002]: [/var/lib/engine/data1/data/dn_6002]], haveFound is 0 CoreDumpCheck ASYN LOG: gaussdb state file "/var/lib/engine/data1/data/dn_6002/gaussdb.state" is not exist, could not get the build infomation: No such file or directory StartAndStop ASYN ERROR: error.dn is 6002 ret=-1 TpNetReportDnGroupInfoMain ASYN LOG: tp net dn report dn group [0] to cms. DnStatus6002 ASYN ERROR: [get_connection: 1446]: fail to read pid file (/var/lib/engine/data1/data/dn_6002/postmaster.pid). DnStatus6002 ASYN ERROR: failed to connect to datanode:/var/lib/engine/data1/data/dn_6002 DnStatus6002 ASYN ERROR: DatanodeStatusCheck failed, ret=-1 DnStatus6002 ASYN LOG: set 6002 on offline.                                步骤 3     查看system_call日志发现打印数据目录权限不足。cd $GAUSSLOG/cm/cm_agent vim system_call-current.log LOG:  assign g_instance_enable_dcf=0 LOG:  configuration file "/var/lib/engine/data1/data/dn_6002/gaussdb.conf" contains errors; unaffected changes were applied CAUSE:  Error from config file occurs and unaffected changes were applied. ACTION:  Use correct config file. FATAL:  data directory "/var/lib/engine/data1/data/dn_6002" has group or world access DETAIL:  Permissions should be u=rwx (0700). CAUSE:  The data directory has group or world access. ACTION:  Add the user to the group or world of the data directory.                                步骤 4     查看该DN数据目录权限为701异常。                                步骤 5     手动将DN数据目录恢复为700权限。                                步骤 6     集群状态恢复。----结束5、2025-115.1 业务SQL包含自定义function,通过hint方式添加query_dop,smp不生效问题现象业务sql执行时间较长,需要通过smp增加并行提升执行效率,通过hint 方式, 发现query_dop 不生效。以下是sql及对应执行计划、相关表表结构。执行计划select表结构insert表结构技术背景针对上述SQL案例,smp使用有如下约束条件,如下:1.         当function为易变函数,smp不生效, 需要将function调整为i函数。2.         当function不能下推到dn执行,smp不生效,需要将function修改为SHIPPABLE。3.         当业务表为分区表且创建了global索引,smp 不生效, 需要将业务表修改为local索引。function创建规则如下l   不主动指定 IMMUTABLE | STABLE , 默认创建 v 函数 | s 函数,即默认指定 VOLATILE | STABLE。l   不主动指定 SHIPPABLE,默认指定 NOT SHIPPABLE, 即该函数不下推到dn上执行。pg_proc 字段说明验证如下l   不主动指定 IMMUTABLE | STABLE , 默认创建 v 函数,即默认指定 VOLATILE。l   不主动指定 SHIPPABLE,默认指定 NOT SHIPPABLE, 即该函数不下推到dn上执行。gaussdb=> CREATE FUNCTION func1 RETURN integer gaussdb->     AS   gaussdb$>     BEGIN gaussdb$>         RETURN 2; gaussdb$>     END; gaussdb$>     / CREATE FUNCTION   --创建function , 默认是v 函数 gaussdb=> select proname, provolatile, proshippable  from pg_proc where proname = 'func1';  proname | provolatile | proshippable  ---------+-------------+--------------  func1   | v           | f验证案例1.         select 查询结果中使用到了v函数(易变 volatile),smp将不生效,需调整为i (不可变的 immutable) 函数或者s(稳定的 stable)函数。gaussdb=> CREATE FUNCTION func1 RETURN integer gaussdb->     AS   gaussdb$>     BEGIN gaussdb$>         RETURN 2; gaussdb$>     END; gaussdb$>     / CREATE FUNCTION   --创建function , 默认是v 函数 gaussdb=> select proname, provolatile, proshippable  from pg_proc where proname = 'func1';  proname | provolatile | proshippable  ---------+-------------+--------------  func1   | v           | f gaussdb=> create table stu2 ( gaussdb(> id int , gaussdb(> sid int, gaussdb(> sname int gaussdb(> ); CREATE TABLE   --默认执行计划 gaussdb=> explain select *, func1 AS pk_id  from stu2;  id |      operation       | E-rows | E-width |    E-costs       ----+----------------------+--------+---------+----------------   1 | ->  Seq Scan on stu2 |   1945 |      12 | 0.000..515.700 (1 row)     --smp 不生效 gaussdb=> explain insert /*+ set(query_dop 4) set(enable_force_smp on)*/ into stu1 select * from stu2;  id |        operation        | E-rows | E-width |    E-costs      ----+-------------------------+--------+---------+----------------   1 | ->  Insert on stu1      |   1945 |      12 | 0.000..515.700   2 |    ->  Seq Scan on stu2 |   1945 |      12 | 0.000..515.700 (2 rows)   --将 func1 修改为 i 函数 gaussdb=> ALTER FUNCTION func1() IMMUTABLE ; ALTER FUNCTION   gaussdb=> select proname, provolatile, proshippable  from pg_proc where proname = 'func1';     proname | provolatile | proshippable     ---------+-------------+--------------     func1   | i           | f    (1 row)     --smp 生效 gaussdb=> explain select /*+ set(query_dop 4) set(enable_force_smp on)*/ *, func1 AS pk_id  from stu2;  id |                 operation                  | E-rows | E-width |    E-costs     ----+--------------------------------------------+--------+---------+---------------   1 | ->  Streaming(type: LOCAL GATHER dop: 1/4) |   1945 |      12 | 0.000..11.992   2 |    ->  Seq Scan on stu2                    |   1945 |      12 | 0.000..7.362 (2 rows)2.         insert 使用了自定义函数,当函数为STABLE/VOLATILE类型的函数,且函数的属性是NOT SHIPPABLE的时候(不能下推到dn执行),smp将不生效,需要调整函数属性为SHIPPABLEgaussdb=> CREATE FUNCTION func2 RETURN integer gaussdb->     AS   gaussdb$>     BEGIN gaussdb$>         RETURN 2; gaussdb$>     END; gaussdb$>     / CREATE FUNCTION   --创建function , 默认不下推dn执行gaussdb=> select proname, provolatile, proshippable  from pg_proc where proname = 'func2';  proname | provolatile | proshippable  ---------+-------------+--------------  func2   | v           | f gaussdb=> create table stu1 ( gaussdb(> id int , gaussdb(> sid int, gaussdb(> sname int, gaussdb(> pk_id int  DEFAULT func2() gaussdb(> ); CREATE TABLE     gaussdb=> create table stu2 ( gaussdb(> id int , gaussdb(> sid int, gaussdb(> sname int gaussdb(> ); CREATE TABLE   --默认执行计划 gaussdb=> explain insert  into stu1 select * from stu2;  id |        operation        | E-rows | E-width |    E-costs     ----+-------------------------+--------+---------+---------------   1 | ->  Insert on stu1      |   1945 |      12 | 0.000..29.450   2 |    ->  Seq Scan on stu2 |   1945 |      12 | 0.000..29.450 (2 rows)   --smp 不生效 gaussdb=> explain insert /*+ set(query_dop 4) set(enable_force_smp on)*/ into stu1 select * from stu2;     id |        operation        | E-rows | E-width |    E-costs         ----+-------------------------+--------+---------+----------------      1 | ->  Insert on stu1      |   1945 |      12 | 0.000..515.700      2 |    ->  Seq Scan on stu2 |   1945 |      12 | 0.000..515.700   -- 调整 func2 函数属性为SHIPPABLE gaussdb=> ALTER FUNCTION func2() SHIPPABLE; ALTER FUNCTION   gaussdb=> select proname, provolatile, proshippable  from pg_proc where proname = 'func2';  proname | provolatile | proshippable  ---------+-------------+--------------  func2   | v           | t     -- smp 生效 gaussdb=> explain insert /*+ set(query_dop 4) set(enable_force_smp on)*/ into stu1 select * from stu2;  id |                 operation                  | E-rows | E-width |    E-costs      ----+--------------------------------------------+--------+---------+----------------   1 | ->  Streaming(type: LOCAL GATHER dop: 1/4) |      0 |       0 | 0.000..493.613   2 |    ->  Insert on stu1                      |   1945 |      12 | 0.000..493.613   3 |       ->  Seq Scan on stu2                 |   1945 |      12 | 0.000..493.613 (3 rows)3.         分区表创建global 索引不支持smp。需要将分区表调整成普通表或者将global索引修改为local索引。gaussdb=> create table stu1( gaussdb(> id int , gaussdb(> sid int, gaussdb(> sname int); CREATE TABLE   gaussdb=> create table stu2 ( gaussdb(> id int , gaussdb(> sid int, gaussdb(> sname int gaussdb(> ) PARTITION BY RANGE (id) ( gaussdb(>     PARTITION p1 VALUES LESS THAN (200), gaussdb(>     PARTITION pmax VALUES LESS THAN (MAXVALUE) gaussdb(> ); CREATE TABLE   --创建global 索引 gaussdb=> CREATE INDEX idx_st2 ON stu2(id) GLOBAL; CREATE INDEX     --默认执行计划 gaussdb=> explain insert  into stu1 select * from stu2;  id |               operation                | E-rows | E-width |    E-costs     ----+----------------------------------------+--------+---------+---------------   1 | ->  Insert on stu1                     |   1945 |      12 | 0.000..29.450   2 |    ->  Partition Iterator              |   1945 |      12 | 0.000..29.450   3 |       ->  Partitioned Seq Scan on stu2 |   1945 |      12 | 0.000..29.450 (3 rows)    Predicate Information (identified by plan id)  -----------------------------------------------    2 --Partition Iterator          Iterations: 2    3 --Partitioned Seq Scan on stu2          Selected Partitions:  1..2 (4 rows)   --smp 不生效 gaussdb=> explain insert /*+ set(query_dop 4) set(enable_force_smp on)*/ into stu1 select * from stu2;  id |               operation                | E-rows | E-width |    E-costs     ----+----------------------------------------+--------+---------+---------------   1 | ->  Insert on stu1                     |   1945 |      12 | 0.000..29.450   2 |    ->  Partition Iterator              |   1945 |      12 | 0.000..29.450   3 |       ->  Partitioned Seq Scan on stu2 |   1945 |      12 | 0.000..29.450 (3 rows)    Predicate Information (identified by plan id)  -----------------------------------------------    2 --Partition Iterator          Iterations: 2    3 --Partitioned Seq Scan on stu2          Selected Partitions:  1..2 (4 rows)   --修改索引为本地索引 gaussdb=> DROP INDEX idx_st2; DROP INDEX gaussdb=>  gaussdb=> CREATE INDEX idx_st2 ON stu2(id) LOCAL; CREATE INDEX   --smp 生效 gaussdb=> explain insert /*+ set(query_dop 4) set(enable_force_smp on)*/ into stu1 select * from stu2;  id |                 operation                  | E-rows | E-width |   E-costs     ----+--------------------------------------------+--------+---------+--------------   1 | ->  Streaming(type: LOCAL GATHER dop: 1/4) |      0 |       0 | 0.000..7.362   2 |    ->  Insert on stu1                      |   1945 |      12 | 0.000..7.362   3 |       ->  Partition Iterator               |   1945 |      12 | 0.000..7.362   4 |          ->  Partitioned Seq Scan on stu2  |   1945 |      12 | 0.000..7.362 (4 rows)    Predicate Information (identified by plan id)  -----------------------------------------------    3 --Partition Iterator          Iterations: 2    4 --Partitioned Seq Scan on stu2          Selected Partitions:  1..2 (4 rows)结论1.         select 语句中使用的ks_auth.F_IS_IDNO为易变函数,smp不生效,需要调整为i函数。2.         insert 对应的表TMP_WATCHLIST_CLIENT_PRE使用的函数dsc_ora_ext.dsc_fn_sys_guid() 不能下推到dn执行,smp不生效,需要修改为SHIPPABLE。3.         T_NOR_CLIENT为分区表且创建了global索引,smp 不生效,需要修改为local索引。5.2 JDBC导入和gsql导入在insert,replace,duplicate方式性能差异问题现象在insert插入数据,发现jdbc方式比gsql方式性能差。通过jdbc和gsql两种方式,对比以下三种插入数据方式,发现性能确实存在差异。l   insert into XXX;l   replace into XXX;l   insert into XXX on duplicate XXX;案例验证1.         gsql方式插入数据并查看耗时−           表结构gaussdb=> create table stu1 (f1 varchar(100), gaussdb(> f2 varchar(100), gaussdb(> f3 varchar(100)); CREATE TABLE−           插入方式insert into stu1 values (generate_series(1,200000),generate_series(1,200000), random() *100::decimal(5,2));   replace into stu2 values (generate_series(1,200000),generate_series(1,200000), random() *100::decimal(5,2));   insert into stu3 values (generate_series(1,200000), generate_series(1,200000), random() *100::decimal(5,2)) on duplicate key update f2 = generate_series(1,200000) + 1, f3=generate_series(1,200000)+1;−           执行耗时−           执行计划insert into XXXreplace into XXXinsert into XXX on duplicate XXXjdbc方式插入数据并查看耗时l   insert 方式l   replace方式l   insert ...duplicate 方式l   执行耗时−           执行计划insert into XXX 执行计划−           replace into XXX−           insert into XXX on duplicate XXX结果差异说明l   gsql方式:三种方式语义一样,在数据库内部只解析一次,走硬解析,一条语句插入20万数据,所以耗时短。l   jdbc方式:a.         insert into t_test (a,id,name) values(?,?,?) 走一次硬解析,20万次软解析,jdbc侧使用executeBatch接口调用,在数据库内部体现为执行了20万次insert,发送一次P报文,20万次UE报文,一个prepare语句多次调用,执行execute。b.         replace into t_test(id,name,a) values (?,?,?) 使用executeBatch接口批量插入20万数据,向内核发送pue报文,在数据库内部体现为执行了20万次insert,语句走一次硬解析,后边调用uE报文执行20万次,与1相同。replace into语句是先删除后更新,返回影响的结果有两行。c.         insert into t_test (id,name,a) values (?,?,?) on duplicate key update a = (a + ?),使用executeBatch接口批量插入20万数据,在数据库内部体现为执行了20万次insert。jdbc调用executeBatch接口向内核发送PUE报文,内部将此语句识别为upsert语句,此类语句不能走gplan计划复用,所以每次执行都会解析计划,耗时长.duplicate语句是原位更新,只影响一行。5.3 主备切换时间长问题分析问题描述客户反馈DN主备切换时间长,需要分析原因分析思路主备切换时间长,通常是因为各个别DN日志回放未完成导致,可根据日志实际进行分析。分析过程1.         查看cm_server主日志,确认cm_server下发升主命令的时间以及下发升主的DN。cd $GAUSSLOG/cm/cm_server vim cm_server-yyyy-mm-dd_******-current.log−           2025-06-20 09:31:13.416(cm_server日志时间差8小时),cm_server主收到上报的dn_6001(原主DN)状态异常,可搜索“ERROR”并根据时间点过滤。−           2025-06-20 09:31:13.475(cm_server日志时间差8小时),cm_server主分别下发Lock1锁命令,对dn_6004,dn_6003,dn_6002进行加锁,可搜索“Lock1 message has sent to instance”关键词。2.         查看dn_6002,dn_6003,dn_6004所在节点的cm_agent日志,确认是否收到cm_server下发的加锁命令。cd $GAUSSLOG/cm/cm_agent vim cm_agent-yyyy-mm-dd_******-current.log−           2025-06-20 09:31:13.478 (cm_agent日志时间差8小时),cm_agent对dn_6004加锁,但加锁失败,可搜索“set Lock1 to instance”关键词。−           期间对dn_6003,dn_6002也在加锁,也是加锁失败,可搜索“set Lock1 to instance”关键词。3.         cm_agent加锁失败,进一步查看DN日志,确认DN在执行什么操作。cd $GAUSSLOG/gs_log/dn_6004vim gaussdb-yyyy-mm-dd_******.log查看dn_6004日志,2025-06-20 17:31:13.477 dn_6004未完成回放,可根据时间点搜索。dn_6002、dn_6003在同一时间点也是未完成回放,此处省略截图。4.         继续查看DN运行日志,确认dn_6002,dn_6003,dn_6004在什么时间完成回放。cd $GAUSSLOG/gs_log/dn_6004 vim gaussdb-yyyy-mm-dd_******.log2025-06-20 17:32:31.517,dn_6004优先回放日志完成,可搜索“redo_done flag is:[true]”关键词。dn_6002、dn_6003在同一时间点未完成回放,此处省略截图。5.         dn_6004优先完成回放,进一步查看cm_server主日志,确认是否下发升主命令以及下发时间。cd $GAUSSLOG/cm/cm_server vim cm_server-yyyy-mm-dd_******-current.log2025-06-20 09:32:32.492(cm_server日志时间差8小时),cm_server主下发dn_6004升主命令,可搜索“Failover message has sent to instance”关键词。6.         查看dn_6004节点的cm_agent日志,确认是否收到dn_6004升主命令以及接收时间。cd $GAUSSLOG/cm/cm_agentvim cm_agent-yyyy-mm-dd_******-current.log2025-06-20 09:32:32.492 (cm_agent日志时间差8小时),cm_agent接受cm_server下发的命令,对dn_6004执行升主操作,可搜索“failover msg from cm_server”关键词。7.         查看dn_6004运行日志,确认是否开始升主以及时间点。cd $GAUSSLOG/gs_log/dn_6004 vim gaussdb-yyyy-mm-dd_******.log2025-06-20 17:32:32.529,dn_6004开始升主,可搜索“Instance to do failover”关键词。8.         继续查看dn_6004运行日志,确认升主完成时间点。cd $GAUSSLOG/gs_log/dn_6004 vim gaussdb-yyyy-mm-dd_******.log2025-06-20 09:32:36.808,dn_6004开始接受新的连接,可搜索“database system is ready to accept connections”关键词。9.         查看dn_6004所在节点的cm_agent日志,确认dn_6004解锁时间。cd $GAUSSLOG/cm/cm_agent vim cm_agent-yyyy-mm-dd_******-current.log2025-06-20 09:32:39.510 (cm_agent日志时间差8小时),cm_agent解锁dn_6004成功,可搜索“process_unlock_no_primary_command succeed”关键词。根本原因综上分析,得出主备切换时间长的原因为:l   dn_6001故障以后,dn_6002,dn_6003,dn_6004日志均与主机存在差距,cm_server分别给dn_6002,dn_6003,dn_6004发下锁DN命令,由于DN回放未完成因此支持锁DN失败,直到2025-06-20 17:32:31.517,dn_6004优先回放完成,因此选择dn_6004升主。l   dn_6004回放耗时:2025-06-20 09:31:13.478--2025-06-20 17:32:31.517,持续78s。l   dn_6004升主耗时:2025-06-20 09:32:32.492--2025-06-20 17:32:39.655,持续7s。因此,主备切换耗时长主要在于回放时间长,回放时间长是由于未开启流控,DN主备之间的RTO高。在升主时先要完成回放再执行升主操作。解决方案开启流控:gs_guc reload -Z datanode -N all -I all -c "recovery_time_target=60"补充说明流控原理说明:在备机回放日志的能力跟不上主机时,通过在walsender线程中进行一定时间的sleep来降低日志发送速度,让备机来得及回放已接收的日志。也就是当备机接收日志或者回放日志的能力跟不上主机时,通过强制降低主机的业务性能,来保证主备机的日志差异在一定目标范围。因此,开启流控,在主机业务压力过大时,会限制主机业务。流控为主机业务压力与RTO两者之间的综合选择,需要根据实际业务特点慎重配置。GaussDB关键日志目录介绍:l   GaussDB日志路径为$GAUSSLOG目录l   CN、DN运行日志路径:$GAUSSLOG/gs_logl   cm_server运行日志:$GAUSSLOG/cm/cm_serverl   cm_agent运行日志:$GAUSSLOG/cm/cm_agentl   升级、安装日志:$GAUSSLOG/om5.4 主机流控导致大量业务超时并且无法新建连接问题现象客户反馈,15:25之前是大量SQL执行超时,从15:25开始无法创建连接。分析思路l   突然出现SQL超时,可能是因为并发突增和、IO打满、资源打满等,可优先通过监控查看资源使用情况以及并发数。l   无法新建连接,可能是因为连接数满、连接不释放、中间件连接数满等情况。问题分析1.         获取业务报错信息。获取业务报错信息,根据业务连接池机制分析以下报错信息,业务连接池连接数为20,当连接被占满并长时间不释放,业务新建连接失败。因此怀疑业务连接池到数据库的连接未及时释放,继续分析数据库相关指标及日志。2024-06-13 15:25:02 [traceId:40093804-1545-4937-ab7e-5246d06de9b7] [ERROR] [http-nio-8015-exec-227] [com.cmfchina.fis.capital.apply.job.CapitalJobController:72] -- capitalStatusRefresh>>>fail org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 20, maxActive 20, creating 0, createErrorCount 12.         查看异常时间段数据库监控指标。−           首先查看资源使用情况,6月13日15:20分左右,cpu、内存使用率无显著突增,表明资源使用无异常。−           其次查看会话连接情况,6月13日15:20分左右,在线会话数略有升高,活跃会话数有显著升高,由15增加到35,表明数据库连接数增加。3.         查看SQL语句分布情况。dn_6001为主DN,根据SQL语句对比,dn_6001上98%的SQL语句为insert语句。当insert语句占比高的时候,通常可能产生流控,因此继续分析流控情况。4.         查看流控相关指标。异常时间段产生主机流控,流控时间达到180000s。  5.         查看DN运行日志。dn_6002,dn_6003均产生流控,同时根据日志,以dn_6002为例,备机接收日志位置为:362E/20A4A000,备机回放位置为:362C/BF72D920,因此表明,备机回放慢导致产生主机流控。6.         分析gs_asp采样数据以及wdr报告。查询gs_asp采样数据以及wdr报告,发现主要的等待事件为:LOGCTRL_SLEEP、wait wal sync,该等待事件表明产生主机流控。7.         查找SQL语句。跟踪WDR报告分析,执行次数最多的两条SQL语句为:3803763747、262602308。进一步根据unique_sql_id,定位到产生流控的主要SQL语句为:1、unique_sql_id为3803763747的INSERT INTO cmf_fis.wind_bondanninf语句;2、unique_sql_id为262602308的INSERT INTO cmf_fis.t_fis_news_port_rel_dm_v4语句。根本原因综上分析:由于大量的insert语句,主机产生xlog多,由于备机回放速率赶不上主机xlog产生速率,触发了主机流控,进而导致已有连接不释放,因此业务新建连接超时。解决措施l   临时解决方案:通常当产生主机流控,执行以下命令关闭流控,进行应急恢复:gs_guc reload -Z datanode -N all -I all -c "recovery_time_target=0"l   长期解决方案:a.         恢复流控参数阈值为30min。gs_guc reload -Z datanode -N all -I all -c "recovery_time_target=1800"b.         开启极致RTO,该参数设置后需要重启集群生效。gs_guc set -Z datanode -N all -I all -c "recovery_parse_workers=2"gs_guc set -Z datanode -N all -I all -c "recovery_redo_workers=4"补充说明l   流控原理说明在备机回放日志的能力跟不上主机时,通过在walsender线程中进行一定时间的sleep来降低日志发送速度,让备机来得及回放已接收的日志。也就是当备机接收日志或者回放日志的能力跟不上主机时,通过强制降低主机的业务性能,来保证主备机的日志差异在一定目标范围。因此,关闭流控,可能存在主备机之间的RTO增大,在主机故障时,主备机切换的时长可能增加。流控为主机业务压力与RTO两者之间的综合选择,需要根据实际业务特点慎重配置。l   极致RTO说明普通串行回放:极致RTO:xLog日志回放建立多级流水线,提高并发度,提升日志回放速度。问题实例CPU利用率均比较低,且产生流控根本原因为备机回放慢导致,因此评估开启极致RTO,可有效提高日志回放速率。5.5 业务分布键选择不合理导致数据分布不均匀问题现象数据磁盘使用率不均衡原因分析客户环境为分布式环境3C3D,从监控指标分析,dn_6001、dn_6002、dn_6003分片的磁盘使用率比其他2个分片高。怀疑是数据分布不均匀导致。分析过程1.         登录到数据库节点,执行如下命令查看数据盘使用率,数据目data1的使用率10%,其他数据目录均为2%。gs_ssh -c "df -h"2.         进入到数据目录data1下,执行如下命令查看文件大小,显示base目录占比最大,怀疑数据分布不均匀。du -sh *3.         执行如下SQL,查询倾斜率较大的表select * from pgxc_get_table_skewness order by skewratio desc limit 10;查询结果可以分析出表“t1”的数据倾斜率为100%,完全倾斜。(一般默认倾斜率大于10%,就代表数据已经倾斜)4.         执行如下SQL,查看表的数据分布情况select schemaname,tablename,nodename,pg_size_pretty(dnsize) dnsize,dnsize/(sum(dnsize) over ()) as percent from table_distribution('root','t1');根据查询结果可以分析出表“t1”的数据全部分布在dn_6001所在的分片5.         查看表“t1”的分布列为“a”,分布方式为hash分布。6.         查看表“t1”字段“a”的值,全部为固定值“1001”综上分析,表“t1”的分布键为固定值,导致数据全部被分布到dn_6001节点,导致该分片所对应的数据目录用率比其他节点高。处理方法建议业务调整分布键,使数据均匀的分布到所有节点,参考分布式表的设计规范:GaussDB 文档中心5.6 DN发生主备切换问题定位问题现象GaussDB 实例主备切换问题分析1.         16:53:14,DN6002与DN6001断联,同时查看DN 主节点,未发现进程异常重启相关文件生成(ffic_log,core文件)。2.         16:53:15,cms主与dn主节点,网络检查失败。3.         16:53:23,CMS主与DN主节点CMA断联,CMS与CMA的连接超时时间受wal_sender_timout参数控制,默认是超过6s连接不上,就会断开连接。4.         同时满足如上两个条件,触发6002升主5.         16:53:30,网络恢复,6001角色上报给cms为主,双主情况下留新主,CMS主下发重启6001命令问题原因网络闪断导致CMS主节点与 DN主节点CMA断联,dn6002与dn6001断联 触发了6002升主。网络恢复后,CMS留新主,重启原主。
  • [问题求助] GaussDB不能执行多个Bind/Describe/Execute然后在最后加一个Flush的操作么
    比如PG可以:GaussDB发现这样就会报EOF错误但是单个的,比如 >B/D/E/H就没事
  • [分享交流] 人形机器人未来发展趋势如何?
    人形机器人未来发展趋势如何?
总条数:1518 到第
上滑加载中