• [技术干货] GaussDB技术解读高性能——数据分区与分区剪枝
    在数据系统中,数据分区是在一个实例内部按照用户指定的策略对数据做进一步的数据切分,将表按照指定规则划分为多个数据互不重叠的部分。从数据分区的角度来看是一种水平分区(horizontal partition)分区策略方式。分区表增强了数据库应用程序的性能、可管理性和可用性,并有助于降低存储大量数据的总体拥有成本。分区允许将表、索引和索引组织的表细分为更小的部分,使这些数据库对象能够在更精细的粒度级别上进行管理和访问。GaussDB Kernel提供了丰富的分区策略和扩展,以满足不同业务场景的需求。由于分区策略的实现完全由数据库内部实现,对用户是完全透明的,因此它几乎可以在实施分区表优化策略以后做平滑迁移,无需潜在耗费人力物力的应用程序更改:(1)改善查询性能,对分区对象的查询可以仅搜索自己关心的分区,提高检索效率(2)增强可用性,如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。(3)方便维护,如果分区表的某个分区出现故障需要修复数据,只修复该分区即可。常见数据库支持的分区表为范围分区表、列表分区表、哈希分区表、间隔分区、组合分区(a.w.k 组合分区)。(1)范围分区(Range Partition):将数据基于范围映射到每一个分区,这个范围是由创建分区表时指定的分区键决定的。这种分区方式是最为常用的。范围分区功能,即根据表的一列或者多列,将要插入表的记录分为若干个范围(这些范围在不同的分区里没有重叠),然后为每个范围创建一个分区,用来存储相应的数据。(2)列表分区(List Partition):将数据基于各个分区内包含的键值映射到每一个分区,分区包含的键值在创建分区时指定。列表分区功能,即根据表的一列,将要插入表的记录中出现的键值分为若干个列表(这些列表在不同的分区里没有重叠),然后为每个列表创建一个分区,用来存储相应的数据。(3)哈希分区(Hash Partition):将数据通过哈希映射到每一个分区,每一个分区中存储了具有相同哈希值的记录。(4)间隔分区(Interval Partition):可以看成是范围分区的一种增强和扩展方式,相比之下间隔分区定义分区时无需为新增的每个分区指定上限和下限值,只需要确定每个分区的长度,实际插入的过程中会自动进行分区的创建和扩展。间隔分区在创建初始时必须至少指定一个范围分区,范围分区键值确定范围分区的高值称为转换点,数据库为值超出该转换点的数据自动创建间隔分区。每个区间分区的下边界是先前范围或区间分区的非包容性上边界。(5)二级分区(Sub Partition,也叫组合分区)是基本数据分区类型的组合,将表通过一种数据分布方法进行分区,然后使用第二种数据分布方式将每个分区进一步细分为子分区。给定分区的所有子分区表示数据的逻辑子集。常见的二级分区组合由Range、List、Hash组成。分区表对查询性能最大的贡献是分区剪枝优化技术,数据库SQL引擎会根据查询条件,只扫描特定的部分分区。分区剪枝是自动触发的,当分区表查询条件符合剪枝场景时,会自动触发分区剪枝。根据剪枝阶段的不同,分区剪枝分为静态剪枝和动态剪枝,静态剪枝在优化器阶段进行,在生成计划之前,数据库已经知道需要访问的分区信息;动态剪枝在执行器阶段进行(执行开始/执行过程中),在生成计划时,数据库并不知道需要访问的分区信息,只是判断“可以进行分区剪枝”,具体的剪枝信息由执行器决定。注意,分区表由于相比普通表多了一层分区选择的处理逻辑,一般而言在数据导入场景下会有一定的性能损耗。
  • [技术解读] GaussDB设计规范
    命名规范数据库对象(库名、表名、字段名、索引名)命名建议全部使用小写字母开头,后面跟字母或者数字,数据库对象(库名、表名、字段名、索引名)名字长度建议都不要大于32字节。 数据库名称不能使用特殊字符("",.,$,,/,*,?,~,#,:,|")和空字符\0,数据库名称不能使用admin,local,config。 数据库集合名称建议使用字母和下划线组合,不能以system为前缀,<数据库名>.<集合名称> 总长度不超过120字符。索引设计规范索引创建,可以避免全表扫描,有效地提高查询命令的执行效率。索引字段的长度不能超过512字节,索引名称长度不能超过64字符,单个复合索引所包含字段数最多不能超过16个。<数据库名>.<集合名>.$<索引名>的总长度不能超过128字符。在高选择性字段上的创建索引。在低选择性字段上查询会返回较大的结果集。尽量避免返回较大的结果集。对集合的写操作同时会操作集合上的索引,从而触发更多的IO操作,集合上的索引数量不要超过32。 不要创建不会被使用到的索引,因为DDS会加载索引到内存,无用索引加载到内存会浪费内存空间因业务逻辑变化而产生的无用索引也要及时清理。索引创建必须使用后台创建索引,禁止前台创建索引。业务中查询,排序条件的key一定要创建索引,如果建立的是复合索引,索引的字段顺序要和这些关键字后面的字段顺序一致,否则索引不会被使用。不要基于复合索引的靠前字段再创建索引。复合索引可以被用于一个索引中主要字段的查询。例如,对于复合索引(firstname,lastname)可以用于在firstname上的查询,再创建一个单独firstname的索引是不必要的。创建索引会消耗较多的IO与计算资源,建议在业务低谷期进行索引创建,禁止同时并发创建超过5条索引。如果需要对同一集合创建多个索引,建议使用createIndexes命令一次性下发多条索引,可以减少性能损耗。分片设计规范对于使用DDS分片集群,建议尽可能的使用分片集合以充分利用性能,详情请参见设置数据分片以充分利用分片性能。分片集合使用上建议如下:对于大数据量(数据量过百万),并有较高读写请求的业务场景,数据量随着业务量增大而增大的,建议采用分片。对于采用hash分片的集合,需要根据业务后面实际数据量大小,采用预分片,提前预置chunk数量,减少自动均衡和分裂对业务运行造成影响。对于非空集合开启分片,应将均衡器的开启时间窗放在业务空闲时,避免分片间均衡数据与业务冲突影响性能。设置时间窗口的API接口详情请参见设置集群均衡活动时间窗。需要基于分片键排序查询且增加数据时可以分布均匀建议使用范围分片,其他使用哈希分片。 合理设计shard key,防止出现大量的数据使用相同shard key,导致出现jumbo chunk。使用分片集群,执行dropDatabase后,一定要执行flushRouterConfig命令,详情请参见如何规避dds mongos路由缓存缺陷。业务的update请求需要注意与片键相适配。在使用分片表时,如果出现如下场景则update请求会报错,并返回“An upsert on a sharded collection must contain the shard key and have the simple collation”。update请求的filter中未携带片键字段且选项multi:falseset中未携带片键字段且选项upsert:true
  • [技术解读] GaussDB开发规范
    GaussDB开发规范数据库连接使用DDS时,可能会遇到因为Mongod/dds mongos的连接数满了,导致客户端无法连接的问题。在Mongod/dds mongos的服务端,收到一个新的连接由一个单独的线程来处理,每个线程配置了1MB的栈空间,当网络连接数太多时,过多的线程会导致上下文切换开销变大,同时内存开销也会上涨。客户端连接数据库的时候,要计算业务一共有多少个客户端,每个客户端配置的连接池大小是多少,总的连接数不要超过当前实例能承受的最大连接数的80%。客户端与数据库的连接应尽量保持相对稳定的状态,每秒新增连接数建议保持在10以下。 建议客户端的连接超时时间至少设置为最大业务执行时长的3倍。对于副本集实例,客户端需要同时配置主备节点的IP地址;对于集群实例,至少配置两个dds mongos的IP地址。DDS默认提供rwuser用户,使用rwuser用户登录时认证库必须是admin。可靠性write concern设置规则:对于关键业务,write concern设置为{w:n},n>0,数字越大,一致性实现更好,但性能较差。w:1表示实际写入主节点完成返回。w:1,journal:true表示写主节点和日志后返回。w:majority表示大多数备节点写入后返回。说明: 如果没有以w:majority写入数据,则发生主备倒换时,未同步到备机的数据有丢失风险。对于可靠性有较高要求的,建议采用3AZ部署的集群。性能相关规范 业务程序禁止执行全表扫描的查询。执行查询时,只选择需要返回的字段,不需要的字段不要返回。从而减少网络和进程处理的负载,修改数据时,只修改变化需要修改的字段,不要整个对象直接存储全部修改。避免使用$not。DDS并不会对缺失的数据进行索引,因此$not的查询条件将会要求在一个结果集中扫描所有记录。如果$not是唯一的查询条件,会对集合执行全表扫描。用$and时把匹配最少结果的条件放在最前面,用$or时把匹配最多结果的条件放在最前面。单个实例中,数据库的总的个数不要超过200个,总的集合个数不要超过500个。集合数量过多会导致内存压力变高,并且集合数量多会导致重启以及主备倒换性能变差,影响紧急情况下的高可用性能。业务上线前,一定要对数据库进行性能压测,评估业务峰值场景下,对数据库的负载情况。 禁止同时执行大量并发事务,且长时间不提交。业务正式上线前, 所有的查询类别,都应该先执行查询计划检查查询性能。建议 每个连接在后台都是由一个单独线程处理,每个线程会分配1MB的栈内存。所以连接数不宜过多,否则会占用过多的内存。使用连接池,避免频繁的建立连接和断开连接,否则会导致CPU过高。减少磁盘读写:避免使用不必要的upsert命令,避免查询不必要的数据。优化数据分布:对数据进行分片,同时分散热点数据,均衡地使用实例资源。如何进行数据分片,请参见设置数据分片。 减少锁冲突:避免对同一个Key过于频繁地操作。减少锁等待:避免前台创建索引。注意开发过程中对集合的每一个操作都要通过执行explain()检查其执行计划,如:db.T_DeviceData.find({"deviceId":"ae4b5769-896f"}).explain(); db.T_DeviceData.find({"deviceId":"77557c2-31b4"}).explain("executionStats");对于查询而言,因为覆盖查询不需要读取文档,而是直接从索引中返回结果,这样的查询性能好,所以尽可能使用索引覆盖查询。如果explain()的输出显示indexOnly字段为真,则说明这个查询就被一个索引覆盖。执行计划解析:看执行时间:executionStats.executionStages.executionTimeMillisEstimate和executionStats.executionStages.inputStage. executionTimeMillisEstimate时间越短越好。executionStats.executionTimeMillis表示执行计划选择和执行的所有时间。executionStats.executionStages.executionTimeMillisEstimate表示执行计划的执行完成时间。executionStats.executionStages.inputStage. executionTimeMillisEstimate表示执行计划下的子阶段执行完成时间。看扫描条数:三个条目数相同为最佳。executionStats. nReturned表示匹配查询条件的文档数。executionStats .totalKeysExamined表示索引扫描条目数。executionStats .totalDocsExamined表示文档扫描条目数。看Stage状态,性能较好的Stage状态组合如下。Fetch+IDHACK Fetch+ixscan Limit+(Fetch+ixscan) PROJECTION+ixscan如果cursor不使用了要立即关闭。由于cursor在10分钟内不活动,就会关闭,立即手动关闭会节省资源。4.2版本分布式事务使用规则 Spring Data MongoDB不支持事务报错后重试机制,如果客户端使用Spring Data Mongo作为连接MongoDB的客户端,需要依照Spring Data Mongo的参考文档,使用Spring Retry进行事务的重试操作。分布式事务操作数据的大小不能超过16MB。备份相关注意事项备份期间应避免进行DDL操作,规避备份失败的风险。 GaussDB官网
  • [技术解读] GaussDB学习笔记之表的选择
     表的选择 1.行存储 默认创建表的类型。数据按行进行存储,即一行数据是连续存储。适用于对数据需要经常更新的场景  gaussdb=# CREATE TABLE customer_t1 (   state_ID   CHAR(2),   state_NAME VARCHAR2(40),   area_ID    NUMBER );  --删除表 gaussdb=# DROP TABLE customer_t1; 2列存储 数据按列进行存储,即一列所有数据是连续存储的。单列查询IO小,比行存表占用更少的存储空间。适合数据批量插入、更新较少和以查询为主统计分析类的场景。列存表不适合点查询。  gaussdb=# CREATE TABLE customer_t2 (   state_ID   CHAR(2),   state_NAME VARCHAR2(40),   area_ID    NUMBER ) WITH (ORIENTATION = COLUMN);  --删除表 gaussdb=# DROP TABLE customer_t2; 3行存表和列存表的选择 更新频繁程度 数据如果频繁更新,选择行存表。  插入频繁程度 频繁的少量插入,选择行存表。一次插入大批量数据,选择列存表。  表的列数 表的列数很多,选择列存表。  查询的列数 如果每次查询时,只涉及了表的少数(<50%总列数)几个列,选择列存表。  压缩率 列存表比行存表压缩率高。但高压缩率会消耗更多的CPU资源。 
  • [问题求助] oracle的 JSON(STRICT)在gaussdb集中式中如何实现等价转换
    oracle的"CONSTRAINT "CK_AZ_ITF_DATA_PARTITION" CHECK (ITF_DATA IS JSON(STRICT)) ENABLE"在gaussdb集中式中如何实现同等转换, json(strict) 这个在gaussdb中不支持,在gaussdb是用函数替代吗。类似如下:1. 创建一个检查 JSON 格式的函数: CREATE OR REPLACE FUNCTION is_json(p_data TEXT) RETURNS BOOLEAN AS $$ BEGIN     -- 尝试将输入的数据解析为 JSON     EXECUTE 'SELECT CAST(' || quote_literal(p_data) || ' AS JSON);';     RETURN TRUE; EXCEPTION WHEN others THEN     RETURN FALSE; END; $$ LANGUAGE plpgsql; 2. 使用该函数创建 CHECK 约束: ALTER TABLE your_table_name ADD CONSTRAINT CK_AZ_ITF_DATA_PARTITION CHECK (is_json(ITF_DATA)); 问题:我这个函数和oracle那个json(strict)是完全等价的吗,如果不符合要求,应该怎样解决呢
  • [问题求助] case语句报错: ERROR: CASE types integer and interval cannot be matched Position: 642 Where: referenced column: XXX
    在执行一个查询语句中,包含case语句,是以前oracle的sql,迁移到高斯执行报错:SELECT CASE WHEN dep_start_date > '2024-11-01 00:00:00' THEN ( to_date( dep_start_date, 'yyyy-mm-dd' ) - to_date( '2024-11-30 23:59:59', 'yyyy-mm-dd' ) + 0 ) + 1 ELSE 30 END days_calFROM fa_cardhistory;报错信息:
  • [问题求助] 使用gorm postgres驱动连接高斯数据无法连接
    数据库版本:gaussdb (GaussDB Kernel 503.1.0.sPc2000 build 8b622ce7) 使用gorm postgres最新驱动连接,提示:failed to receive message(AuthenticationSASL body is invalid unterminated string)连接dsn格式: host=127.0.0.1 user=admin dbname=test sslmode=disable password=admin port=5432
  • [问题求助] tpops添加主机,检查python不通过,怎么回事
    tpops添加主机,检查python不通过,怎么回事
  • [问题求助] 【小白求助】为什么在gaussdb里面,表文件没有fsm和vm文件
    select oid,relfilenode,relname from pg_class where relname ='teacher'; oid | relfilenode | relname -------+-------------+--------- 17530 | 17542 | teacher然而在操作系统里面,只找到17542这个文件,没有像_vm,_fsm这些文件[Ruby@gauss-dis-134 base]$ find ./ -name 17542* ./17325/17542像在postgresql,openGauss,都是有_fsm,_vm的文件的
  • [问题求助] 【小白求助】为什么base目录下数据库目录名称与pg_database视图中的oid不匹配
    在postgresql或者openGauss中,数据文件目录的base目录下,名称和oid都是一一对弈对应的,如:openGauss=# select oid,datname from pg_database; oid | datname -------+------------- 1 | template1 16398 | db_web_data 15649 | template0 16400 | db_test2 16399 | db_test1 15654 | postgres 16405 | db_test123对应着文件系统的目录[omm@txy base]$ ls -ls total 120 20 drwx------ 2 omm dbgrp 20480 Oct 12 10:15 1 16 drwx------ 2 omm dbgrp 16384 Oct 12 10:15 15649 16 drwx------ 2 omm dbgrp 16384 Nov 3 23:24 15654 16 drwx------ 2 omm dbgrp 16384 Oct 16 15:44 16398 16 drwx------ 2 omm dbgrp 16384 Oct 23 17:03 16399 16 drwx------ 2 omm dbgrp 16384 Oct 23 17:03 16400 16 drwx------ 2 omm dbgrp 16384 Oct 23 17:25 16405 4 drwx------ 2 omm dbgrp 4096 Oct 12 10:14 pgsql_tmp但是在gaussdb,我发现并不是一样的gaussdb=> select oid,datname from pg_database; oid | datname -------+------------ 1 | template1 14942 | template0 17325 | db_ora 17457 | db_conn10w 17458 | db_default 14948 | postgres 16809 | test在文件目录里面反而是这些?[Ruby@gauss-dis-133 base]$ ls -lsa total 160 4 drwx------ 10 Ruby Ruby 4096 Nov 9 14:29 . 4 drwx------ 22 Ruby Ruby 4096 Nov 9 14:51 .. 16 drwx------ 2 Ruby Ruby 16384 Nov 9 08:18 1 16 drwx------ 2 Ruby Ruby 16384 Nov 9 08:18 14942 24 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 14948 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 16763 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 25211 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 25294 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 25295新建一个数据库gaussdb=> create database db_newdb; gaussdb=> select oid,datname from pg_database; oid | datname -------+------------ 1 | template1 14942 | template0 17325 | db_ora 17457 | db_conn10w 17458 | db_default 14948 | postgres 16809 | test 17521 | db_newdb很明显会发现多了33483这个目录,可是我新建这个db_newdb的oid是17521啊,为什么对不上呢?[Ruby@gauss-dis-133 base]$ ls -lsa total 160 4 drwx------ 10 Ruby Ruby 4096 Nov 9 14:29 . 4 drwx------ 22 Ruby Ruby 4096 Nov 9 14:51 .. 16 drwx------ 2 Ruby Ruby 16384 Nov 9 08:18 1 16 drwx------ 2 Ruby Ruby 16384 Nov 9 08:18 14942 24 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 14948 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 16763 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 25211 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 25294 20 drwx------ 2 Ruby Ruby 20480 Nov 9 08:18 25295 16 drwx------ 2 Ruby Ruby 16384 Nov 9 14:29 33483```
  • [问题求助] 小白求助:为什么在CN目录下面也会有数据文件?
    以下是我在三节点分布式gaussdb上面查询到的结果:### cn里面也有数据文件 [root@gauss-dis-134 cn]# du -sh base 123M base [root@gauss-dis-134 cn]# du -sh global 514M global ### dn的大小 [root@gauss-dis-134 dn_6002]# du -sh base 255M base [root@gauss-dis-134 dn_6002]# du -sh global 514M global我的问题是:这是在同一个机器上面,为什么在cn目录下面也有base、global这些文件(里面是数据文件) 官方文档的描述里面不是说,由datanode负责数据的存储,cn只负责协调吗?如果同一台机器,cn和dn都存一样的数据,不会浪费空间吗?
  • [数据库使用] 小数点前0不显示问题
    小数点前0不显示postgres=# select 0.1 as result; result -------- .1(1 row)小数点前0会省略,是因为数据库中存在一个隐形类型转换,在拼接的过程中小数自动转成字符类型,相当于调用了to_char函数,所以丢失小数点前面的0解决方法:使用to_char进行转换-- 数字转字符串格式select to_char(a, 'FM9990.00')"FM9990D00", to_char(a, '99.90')"99D90", to_char(a, 'FM90D99')"FM90D99", rtrim(to_char(a, 'FM999990D99'), to_char(0, 'D'))"FM999990D99" from ( select 50 a from dual union all select 50.57 from dual union all select 5.57 from dual union all select 0.35 from dual union all select 0.4 from dual) FM9990D00 | 99D90 | FM90D99 | FM999990D99 -----------+--------+---------+------------- 50.00 | 50.00 | 50. | 50 50.57 | 50.57 | 50.57 | 50.57 5.57 | 5.57 | 5.57 | 5.57 0.35 | .35 | 0.35 | 0.35 0.40 | .40 | 0.4 | 0.4四种常用格式对比:【FM9990.00】格式,皆满足;代码更简洁;与【rtrim(to_char(a, 'FM999990D99'), to_char(0, 'D'))"FM999990D99"】的区别整数是否保留小数。【99D90】格式,问题:小数位小于1,0则不显示。【FM90D99】格式,问题:小数位为0,则不显示。【rtrim(to_char(a, 'FM999990D99'), to_char(0, 'D'))"FM999990D99"】格式,缺点:代码过于复杂化。注:【9】在小数位,则表示转换为对应字符,如果没有则以0表示;在整数位,没有对应则不填充字符。to_char(123,'999D99')=123.00;to_char(123,'99999D9')=123.0;注意事项:对于0和9而言,如果格式的位数不如数字的位数多,会返回'#'。譬如to_char(12345,'9999')='#####' 。 【0】代表如果存在数字则显示数字,不存在则显示0,即占位符;to_char(0.34,'0D00')=​'0.34';to_char(1234,'9999D00')='1234.00';注意事项:这是一个强制的符号,对应位没有,则以'0'填充,这是9很大不同地方。【D】(ISO 小数位符号) '999D99' 这是"点号"的国际版本(ISO),作用等同于点号,也是只能出现一次,也可以直接用'.'。【FM】代表删除如果是因9带来的空格,则删除,小数点后的9。
  • [问题求助] gaussdb不支持insert into select file_fdw
    GaussDB在使用外部表file_fdw时,无法使用insert into select file_fdw语法提示un-support feature,修改什么属性才可以支持这种语法?
  • [问题求助] 小小白求助:win10系统,psycopg2连接GaussDB报错:none of the server's SASL authentication mechanisms are supported
    小小白,测试人员刚刚接触Gaussdb,新人求助、求指导。【系统配置】win10系统pycharmpython3.8已安装第三方库psycopg2-binary 2.9.3(手动下载whl并安装的)GaussDB: 有集中式和分布式的,不同的IP而已opengauss:使用psycopg2可以正常连接opengauss数据库使用Navicat16版本可以正常连接opengauss、GaussDB分布式/集中式【问题描述】使用psycopg2可以正常连接opengauss数据库。目前想要连接云数据库GaussDB,但不能连接成功。导入psycopg2驱动后,连接数据库,连接不成功,报错。【报错信息】报错信息如下: connection to server at "10.XX.XX.XX", port 30000 failed: none of the server's SASL authentication mechanisms are supported【相关截图】之前也有找官方文档,但里面的都是基于linux环境的,且下载驱动仅支持欧拉和银河麒麟系统。没有windows的
  • [运维管理] sql在查询时写关联,select xx from a left join b on a.i=b.i left join c on a.i=c.i left join d on a.i=d.i...这种写法有什么问题不?
    sql在查询时写关联,select xx from a left join b on a.i=b.i left join c on a.i=c.i left join d on a.i=d.i...这种写法有什么问题不?a 表数据是否会随着关联数据翻倍?
总条数:1666 到第
上滑加载中