华为云用户手册

  • 处理方法 方法一 该处理方法仅8.1.3及以上集群版本支持。 登录 GaussDB (DWS) 管理控制台。 在集群列表中单击指定集群名称。 进入“集群详情”页面,切换至“智能运维”页签。 在运维详情部分切换至运维计划模块。单击“添加运维任务”按钮。 弹出添加运维任务边栏。 运维任务选择“Vacuum”。 调度模式选择“指定目标”,智能运维将在指定时间窗内,自动下发表级Vacuum任务。 用户可配置需要Vacuum的列存表,其中一行对应一张表,每张表以数据库名、模式名、表名表示,以空格进行分割。 单击“下一步:定时配置”,配置Vacuum类型,推荐选择“周期型任务”,GaussDB(DWS)将自动在自定义时间窗内执行Vacuum。 确认无误后,单击“下一步:配置确认”,完成配置。 方法二 对列存表更新操作后,需要进行VACUUM FULL清理,更多用法请参见VACUUM的“VACUUM”章节。 1 VACUUM FULL table_name;
  • 问题现象 通过JDBC连接集群执行COPY导入时报错: org.postgresql.util.PSQLException: Database connection failed when starting copy at org.postgresql.core.v3.QueryExecutorImpl.startCopy(QueryExecutorImpl.java:804) at org.postgresql.copy.CopyManager.copyIn(CopyManager.java:52) at org.postgresql.copy.CopyManager.copyIn(CopyManager.java:161) at org.postgresql.copy.CopyManager.copyIn(CopyManager.java:146) at copy.main(copy.java:95) Caused by: java.io.EOFExceptionat org.postgresql.core.PGStream.ReceiveChar(PGStream.java:284) at org.postgresql.core.v3.QueryExecutorImpl.processCopyResults(QueryExecutorImpl.java:1008) at org.postgresql.core.v3.QueryExecutorImpl.startCopy(QueryExecutorImpl.java:802) ... 4 more
  • 处理方法 数据库的兼容模式在CREATE DATABASE时由DBCOMPATIBILITY参数指定。 DBCOMPATIBILITY [ = ] compatibility_type 指定兼容的数据库的类型。 取值范围:ORA、TD、MySQL。分别表示兼容Oracle、Teradata和MySQL数据库。 若创建数据库时不指定该参数,默认为ORA。 为解决DATABASE的兼容性模式问题,需要将两个数据库的兼容模式修改为一致。GaussDB(DWS)不支持ALTER方式修改已有数据库的兼容模式DBCOMPATIBILITY,只能通过新建数据库的方式来指定兼容模式。 12 CREATE DATABASE td_db DBCOMPATIBILITY ='TD';CREATE DATABASE GaussDB(DWS)不同兼容模式下Oracle、Teradata和MySQL语法行为会有一些差异,具体的差异内容可参考Oracle、Teradata和MySQL语法兼容性差异。
  • 原因分析 GaussDB(DWS)支持Oracle、Teradata和MySQL数据库兼容模式。 在TD/MySQL兼容模式下,空和NULL是不相等的,在ORA兼容模式下,空和NULL是相等的。因此上述场景可能是因为两个环境中数据库的兼容性模式设置不一致导致。 可通过查询PG_DATABASE系统表确认数据库的兼容模式: 1 SELECT datname, datcompatibility FROM pg_database;
  • 处理方法 使用GRANT语法对表/schema进行赋权,示例: 假设当前有两个用户tom和jerry,如果想要用户jerry能够对当前tom创建的所有表以及将来创建的表都有查询权限,如何处理: 将用户tom下的同名schema权限赋给jerry。 1 GRANT USAGE ON SCHEMA tom TO jerry; 将用户tom已经创建的表的select权限赋给jerry。 1 GRANT SELECT ON ALL TABLES IN SCHEMA tom TO jerry; 将用户tom未来在同名schema下创建的表的select权限赋给jerry。 1 ALTER DEFAULT PRIVILEGES FOR USER tom IN SCHEMA tom GRANT SELECT ON TABLES TO jerry;
  • 问题现象 数据库中新建一张表,某个表字段使用character类型,在Java中读取character类型的字段时返回类型是byte。 例如,创建示例表table01: 1234 CREATE TABLE IF NOT EXISTS table01( msg_id character(36), msg character varying(50)); 在Java中,读取character类型的字段代码如下: 1 ColumnMetaInfo(msg_id,1,Byte,true,false,1,true);
  • 处理方法 方法一:分布键目前暂不支持更新,直接跳过该报错。 方法二:将分布列修改为一个不会更新的列(8.1.0版本后,支持调整分布列,以下为示例)。 查询当前表定义,返回结果显示该表分布列为c_last_name。 1 SELECT pg_get_tabledef('customer_t1'); 更新分布列中的数据时报错。 1 UPDATE customer_t1 SET c_last_name = 'Jimy' WHERE c_customer_sk = 6885; 将该表的分布列修改为不会更新的列,例如c_customer_sk。 1 ALTER TABLE customer_t1 DISTRIBUTE BY hash (c_customer_sk); 重新执行更新旧的分布列的数据。更新成功。 1 UPDATE customer_t1 SET c_last_name = 'Jimy' WHERE c_customer_sk = 6885;
  • 区域支持 区域支持指的是应用遵守文化偏好的问题,包括字母表、排序、数字格式等。区域是在使用initdb创建一个数据库时自动被初始化的。默认情况下,initdb将会按照它的执行环境的区域设置初始化数据库,即系统已经设置好的区域。如果想要使用其他的区域,可以使用手工指定(initdb –locale=xx)。 如果想要将几种区域的规则混合起来,可以使用以下区域子类来控制本地化规则的某些方面。这些类名转换成initdb的选项名来覆盖某个特定分类的区域选择。 表1 区域支持 字段 描述 LC_COLLATE 字符串排序顺序。 LC_CTYPE 字符分类(什么是一个字符?它的大写形式是否等效?) LC_MESSAGES 消息使用的语言Language of messages。 LC_MONETARY 货币数量使用的格式。 LC_NUMERIC 数字的格式。 LC_TIME 日期和时间的格式。
  • 原因分析 以UTF-8编码为例,一个中文占3~4个字节,即8个中文占24~32字节,超出VARCHAR(18)的最大18字节限制。 当表中某一字段包含有中文字符时,可使用char_length或length函数来查询字段字符长度,使用lengthb函数来查询字段字节长度。 12345 SELECT length('数据库database'); length-------- 11(1 row) 12345 SELECT lengthb('数据库database'); length-------- 17(1 row)
  • 字符集 PG里面的字符集支持各种字符集存储文本,包括单字节字符集,比如ISO 8859系列,以及多字节字符集,比如EUC(扩展Unix编码Extended Unix Code)、UTF-8和Mule内部编码。MPPDB中目前主要使用的字符集包括GBK、UTF-8和LATIN1。所有被支持的字符集都可以被客户端透明地使用,但少数只能在服务器上使用(即作为一种服务器端编码,GBK编码在PG中只是客户端编码,不是服务端编码,MPPDB将GBK引入到服务端编码,这是很多问题的根源)。默认的字符集是在使用initdb初始化PG数据库时选择的。在创建一个数据库实例时可以重载字符集,因此可能会有多个数据库实例并且每一个使用不同的字符集。一个重要的限制是每个数据库的字符集必须和数据库LC_CTYPE(字符分类)和LC_COLLATE (字符串排序顺序)设置兼容。对于C或POSIX,任何字符集都是允许的,但是对于其他区域只有一种字符集可以正确工作。不过,在Windows上UTF-8编码可以和任何区域配合使用。 SQL_ASCII设置与其他设置表现得相当不同。如果服务器字符集是SQL_ASCII,服务器把字节值0-127根据ASCII标准解释,而字节值128-255则当作无法解析的字符。如果设置为SQL_ASCII,就不会有编码转换。因此,这个设置基本不是用来声明所使用的指定编码,因为这个声明会忽略编码。在大多数情况下,如果使用了任何非ASCII数据,那么使用SQL_ASCII设置都是不明智的,因为PG将无法帮助你转换或者校验非ASCII字符。 数据库系统支持某种编码,主要涉及三个方面:数据库服务器支持,数据访问接口支持以及客户端工具支持。 数据库服务器字符编码 数据库服务器支持某种编码,是指数据库服务器能够从客户端接收、存储以及向客户端提供该种编码的字符(包括标识符、字符型字段值),并能将该种编码的字符转换到其它编码(如UTF-8编码转到GBK编码)。 指定数据库服务器编码:创建数据库时指定:CREATE DATABASE … ENCODING … //可以取ASCII、UTF-8、EUC_CN、……; 查看数据库编码:show server_encoding。 数据库访问接口编码 数据库访问接口支持某种编码,是指数据库访问接口要做到能对该种编码的字符进行正确读写,不应出现数据丢失、数据失真等情况。以JDBC接口为例: JDBC接口一般根据JVM的file.encoding设置client_encoding:set client_encoding to file_encoding; 将String转换成client_encoding编码的字节流,传给服务器端:原型String.getBytes(client_encoding) ; 收到服务器的字节流后,使用client_encoding构造String对象作为getString的返回值给应用程序:原型String(byte[], …, client_encoding)。 客户端编码 客户端工具支持某种编码,是指客户端工具能够显示从数据库读取该种编码的字符,也能通过本工具将该种编码的字符提交到服务器端。 指定会话的客户端编码:SET CLIENT_ENCODING TO 'value'; 查看数据库编码:Show client_encoding。
  • 原因分析 GaussDB(DWS)支持Hash、REPLICATION和ROUNDROBIN(8.1.2集群及以上版本支持ROUNDROBIN)分布方式。如果创建了Hash分布的表,未指定分布键,则选择表的第一列作为分布键,这种情况就可能存在倾斜。倾斜造成以下负面影响: SQL的性能会非常差,因为数据只分布在部分DN,那么SQL运行的时候就只有部分DN参与计算,没有发挥分布式的优势。 会导致资源倾斜,尤其是磁盘。可能部分磁盘的空间已经接近极限,但是其他磁盘利用率很低。 可能出现部分节点CPU过高等问题。
  • 处理方法 String_agg中增加order by,语句修改为如下格式保证ename字段是按照相同的顺序来拼接的,从而满足查询结果是稳定的。 1234 select count(*) from(select deptno, string_agg(ename, ',' order by ename desc) from employee group by deptno) t1 ,(select deptno, string_agg(ename, ',' order by ename desc) from employee group by deptno) t2where t1.string_agg = t2.string_agg;
  • 处理方法 建议对单个表执行VACUUM FULL命令,命令格式为“VACUUM FULL 表名”。 如果您对表没有权限,请联系数据库管理员或表的所有者进行处理。 对于vacuum_defer_cleanup_age不是0的场景,可以将此参数改为0,取消VACUUM的事务延迟。 对于存在老事务的场景,重启集群再重新执行VACUUM FULL可以保证空间一定回收,否则只能等老事务结束再执行VACUUM FULL。
  • 问题现象 DWS中有两种情况需要关注表是否做过UPDATE及DELETE操作: 对表频繁执行UPDATE或者DELETE操作会产生大量的磁盘页面碎片,从而逐渐降低查询的效率,需要将磁盘页面碎片恢复并交还操作系统,即VACUUM FULL操作,这种场景下需要查找出哪些表执行过UPDATE; 判断一张表是否是维度表,是否可以从Hash表变更为复制表,可以查看这张表是否执行过UPDATE或DELETE,如果执行过UPDATE或DELETE操作,则不能修改为复制表。
  • 原因分析 执行VACUUM时,对某些表可能没有权限,或者数据库本身并没有太多的数据膨胀。 执行VACUUM,默认清理当前用户在数据库中拥有权限的每一个表,没有权限的表则直接跳过回收操作。 参数vacuum_defer_cleanup_age不是0,该参数在老版本默认为8000,表示最近8000个事务产生的脏数据不进行回收。 为了保证事务可见性,产生脏数据的事务号,如果大于当前活跃的老事务号,则这部分脏数据也不会清理。
  • 处理方法 通过以下命令查找哪些表执行过UPDATE及DELETE操作: 123456789 ANALYZE tablename;SELECT n.nspname , c.relname, pg_stat_get_tuples_deleted(x.pcrelid) as deleted,pg_stat_get_tuples_updated(x.pcrelid) as updatedFROM pg_class cINNER JOIN pg_namespace n ON n.oid = c.relnamespaceINNER JOIN pgxc_class x ON x.pcrelid = c.oidWHERE c.relkind = 'r' and c.relname='tablename' ;
  • 原因分析 某业务场景中的SQL语句中使用了string_agg函数,语句逻辑如下: 执行如下SQL语句: 1234 select count(*) from(select deptno, string_agg(ename, ',') from employee group by deptno) t1 ,(select deptno, string_agg(ename, ',') from employee group by deptno) t2where t1.string_agg = t2.string_agg;
  • 原因分析 业务数据文件从Oracle导入,文件编码为utf-8。该报错还会提示行数,由于文件特别大,vim命令打不开文件,于是用sed命令把报错行数提出来,再用vim命令打开,发现并没有什么异常。用split命令按行数切割后,部分文件也可以导入。 经分析GaussDB(DWS)的varchar型的字段或变量不允许含有'\0'(也即数值0x00、UTF编码'\u0000')的字符串 ,需在导入前去掉字符串中的'\0'。
  • 问题现象 查看日志提示: [ERROR] Mpp task queryDataAnalyseById or updateDataAnalyseHistoryEndTimesAndResult fail, dataAnalyseId:17615 org.postgresql.util.PSQLException: ERROR: memory is temporarily unavailablesql:vacuum full dws_customer_360.t_user_resource;
  • 如何选择公有云GaussDB(DWS)或者公有云RDS? 公有云GaussDB(DWS)和公有云RDS都让您能够在云中运行传统的关系数据库,同时转移数据库管理负载。您可将RDS数据库用于联机事务处理 (OLTP) ,报告和分析,对于大量数据的读(一般是复杂的只读类型查询)支持不足。GaussDB(DWS)利用多节点的规模和资源并使用各种优化法(列存,向量引擎,分布式框架等),专注于联机分析处理(OLAP),为传统数据库对大型数据集的分析及报告工作负荷提供了数量级改善。 当您的数据及查询的复杂性增加时,或者在您要防止报告和分析处理对OLTP工作负荷造成干扰时,GaussDB(DWS)可提供横向扩展能力。 您可以根据下表简单判断什么场景更适合用GaussDB(DWS)或RDS。 表1 OLTP和OLAP特性比较 特性 OLTP OLAP 用户 操作人员,低层管理人员 决策人员,高级管理人员 功能 日常操作处理 分析决策 设计 面向应用 面向主题 数据 最新的,细节的,二维的,分离的 历史的,集成的,多维的,统一的 存取 读/写数十条记录 读上百万条记录 工作范围 简单的读写 复杂的查询 数据库大小 百GB TB-PB级别 父主题: 产品咨询
  • GaussDB(DWS)是否支持第三方客户端以及JDBC和ODBC驱动程序? 推荐使用GaussDB(DWS)客户端和驱动程序。与开源的PostgreSQL客户端和驱动程序相比,有两个主要的优点: 安全强化:PostgreSQL驱动程序只支持MD5认证,但GaussDB(DWS)驱动程序支持SHA256和MD5。 数据类型增强:GaussDB(DWS)驱动程序支持新的数据类型smalldatetime和tinyint。 GaussDB(DWS)支持开源PostgreSQL客户端和JDBC和ODBC驱动程序。 兼容的客户端和驱动程序版本如下: PostgreSQL的psql 9.2.4或更高版本 PostgreSQL JDBC驱动程序9.3-1103或更高版本 PSQL ODBC 09.01.0200或更高版本 使用JDBC/ODBC连接GaussDB(DWS),可参见《 数据仓库 服务开发指南》的教程:使用JDBC或ODBC开发。 建议使用官方推荐的方式连接数据库。参见连接集群方式。 其它客户端不能保证100%兼容性,需要客户自行验证。 使用其它客户端如果出现不兼容而报错,且不能替换客户端的情况,可尝试替换客户端中的libpq驱动。替换方法:参见工具下载下载并解压gsql客户端压缩包,获取gsql目录下的libpg.so,替换到客户端指定目录中。 父主题: 数据库连接
  • 为什么GaussDB(DWS)的性能在极端场景下并未比单机数据库好 GaussDB(DWS)中由于MPP架构的限制导致少部分PG系统方法、函数无法下推到DN节点来执行,仅能在CN端出现性能瓶颈。 原理解释: 一个操作能够并行执行是有条件的,需要逻辑上能够并行,比如做汇总(SUM),可以各个节点(DN)并行汇总后,最后的汇总一定是不能并行,要在某一个节点(CN)上执行,由于大部分的汇总工作已经在DN节点完成,CN端的工作是比较轻量的。 某些场景必须要集中执行,比如事务号,必须要保证全局唯一,该任务在系统里是通过GTM来实现的,因此,GTM也是全局唯一的组件(主备)。所有需要全局唯一的任务都是通过GaussDB(DWS)中的GTM来完成,只是在设计上尽量避免阻塞在GTM上,因此GTM并没有太多瓶颈,而且有些场景下还可以GTM-Free和GTM-Lite。 从传统单机数据库的应用开发模式到并行数据库,为确保获得更好的性能,可能需要对业务进行少量改动,尤其是传统Oracle的存储过程互相嵌套的开发模式,如果要保证高性能,需要进行业务修改及对应的适配。 解决方案: 如遇到此类问题,请参考《数据仓库服务数据库开发指南》中的“优化查询性能”章节。 或者,请联系技术人员进行业务适配的修改调优。 父主题: 数据库性能
  • 查询分区边界 123456789 SELECT relname, partstrategy, boundaries FROM pg_partition where parentid=(select parentid from pg_partition where relname='my_table'); relname | partstrategy | boundaries-------------+--------------+------------ my_table | r | my_table_p1 | r | {600} my_table_p2 | r | {800} my_table_p3 | r | {950} my_table_p4 | r | {1000}(5 rows)
  • 查询数据在各DN分布 1 2 3 4 5 6 7 8 910 SELECT table_skewness('my_table'); table_skewness------------------------------------ ("dn_6007_6008 ",3,50.000%) ("dn_6009_6010 ",2,33.333%) ("dn_6003_6004 ",1,16.667%) ("dn_6001_6002 ",0,0.000%) ("dn_6005_6006 ",0,0.000%) ("dn_6011_6012 ",0,0.000%)(6 rows)
  • 查询某一有数据分布DN上分区P1所对应的cudesc和delta表名称 123456 EXECUTE DIRECT ON (dn_6003_6004) 'select a.relname from pg_class a, pg_partition b where (a.oid=b.reldeltarelid or a.oid=b.relcudescrelid) and b.relname=''my_table_p1'''; relname---------------------- pg_delta_part_60317 pg_cudesc_part_60317(2 rows)
  • 检查原因 基本原因可能有以下几种: 集群状态是否正常。 连接命令是否正确,用户名、密码、IP地址或端口无误。 安装客户端的操作系统类型、版本是否正确。 安装客户端的操作是否正确。 如果是在公有云环境无法连接,还需要检查以下可能导致异常的原因: 弹性云服务器是否与集群在相同可用分区、虚拟私有云、子网和安全组。 安全组的出入规则是否正确。 如果是在互联网环境无法连接,还需要检查以下可能导致异常的原因: 用户网络是否与互联网可以正常连通。 用户网络防火墙策略是否限制了访问。 用户网络是否需要通过代理才能访问互联网。
  • 使用UN LOG GED表 场景: 使用unlogged表后,在集群重启后,关联查询结果集异常,查看unlogged表缺少部分数据。 原因分析: 如果设置max_query_retry_times为0,且在建表时指定UNLOGGED关键字,则创建的表为非日志表。在非日志表中写入的数据不会被写入到预写日志中,这样就会比普通表快很多。但是非日志表在冲突、执行操作系统重启、强制重启、切断电源操作或异常关机后会被自动截断,会造成数据丢失的风险。非日志表中的内容也不会被复制到备服务器中。在非日志表中创建的索引也不会被自动记录。因此当集群发生异常重启(进程重启、节点故障、集群重启)时,会导致部分内存中的数据未及时落盘,造成部分数据丢失,从而导致结果集异常。 解决方法: unlogged表在集群异常情况下的安全性无法保证,一般不能作为业务表使用,更多的场景是作为临时表使用。当出现集群故障后,为了保证数据正常,需要重建unlogged表或将数据备份后重新导入数据库。
  • 子视图/子查询中使用排序 场景: 创建表test和视图v后,子查询中使用排序查询表test,出现查询结果不一致。 123456 CREATE TABLE test(a serial ,b int);INSERT INTO test(b) VALUES(1);INSERT INTO test(b) SELECT b FROM test;…INSERT INTO test(b) SELECT b FROM test;CREATE VIEW v as SELECT * FROM test ORDER BY a; 问题SQL: 1 2 3 4 5 6 7 8 91011121314151617 SELECT * FROM v limit 1; a | b---+--- 3 | 1(1 row)SELECT * FROM (select * from test order by a) limit 10; a | b----+--- 14 | 1(1 row)SELECT * FROM test order by a limit 10; a | b---+--- 1 | 1(1 row) 原因分析: 对于子视图和子查询中order by是无效的。 解决方法: 不建议在子视图和子查询中使用order by,若要保证结果有序,需在最外层查询中使用order by。
  • 使用string_agg 场景:使用string_agg查询表employee,出现查询结果不一致。 1 2 3 4 5 6 7 8 910111213141516171819 SELECT * FROM employee; empno | ename | job | mgr | hiredate | sal | comm | deptno -------+--------+---------+------+---------------------+-------+------+-------- 7654 | MARTIN | SALEMAN | 7698 | 2022-11-08 00:00:00 | 12000 | 1400 | 30 7566 | JONES | MANAGER | 7839 | 2022-11-08 00:00:00 | 32000 | 0 | 20 7499 | ALLEN | SALEMAN | 7698 | 2022-11-08 00:00:00 | 16000 | 300 | 30(3 rows)SELECT count(*) FROM (select deptno, string_agg(ename, ',') from employee group by deptno) t1, (select deptno, string_agg(ename, ',') from employee group by deptno) t2 where t1.string_agg = t2.string_agg; count ------- 2(1 row)SELECT count(*) FROM (select deptno, string_agg(ename, ',') from employee group by deptno) t1, (select deptno, string_agg(ename, ',') from employee group by deptno) t2 where t1.string_agg = t2.string_agg; count ------- 1(1 row) 原因分析: String_agg函数的作用是将组内的数据合并成一行,但是如果某用户的用法是string_agg(ename, ',') ,结果集就是不稳定的,因为没有指定组合的顺序。例如,上述语句中,对于select deptno, string_agg(ename, ',') from employee group by deptno; 输出结果既可以是: 1 30 | ALLEN,MARTIN 也可能是: 1 30 |MARTIN,ALLEN 两个结果都是合理的,因此上述关联场景下,有可能出现t1这个subquery中的结果和t2这个subquery中的结果对于deptno=30时的输出结果不一致。 解决方法: String_agg中增加order by排序,保证按顺序拼接。 1 SELECT count(*) FROM (select deptno, string_agg(ename, ',' order by ename desc) from employee group by deptno) t1 ,(select deptno, string_agg(ename, ',' order by ename desc) from employee group by deptno) t2 where t1.string_agg = t2.string_agg;
  • 数据库兼容模式 场景:在数据库中查询空串结果不一致。 database1(TD兼容模式): 12345 td=# select '' is null; isnull -------- f(1 row) database2(ORA兼容模式): 12345 ora=# select '' is null; isnull -------- t(1 row) 原因分析: 查询空串结果不同是由于不同数据库兼容模式下空串与null语法有差异导致。 目前,GaussDB(DWS)支持三种数据库兼容模式:Oracle、TD和MySql,不同兼容模式下语法和行为存在差异,兼容性差异说明可参考Oracle、Teradata和MySQL语法兼容性差异。 不同兼容模式下的database表现出不同的兼容性行为属于正常现象。可以通过查看select datname, datcompatibility from pg_database;确认数据库兼容性设置是否相同。 解决方法: 这种场景下只能将两个database的兼容性模式设置为一致的才能解决。Database的DBCOMPATIBILITY属性不支持ALTER,只能通过新建数据库的方法,在创建数据库时指定相同的DBCOMPATIBILITY属性解决。
共99354条