华为云用户手册

  • 问题现象 向表中插入数据报错:duplicate key value violates unique constraint "%s"。 1 2 3 4 5 6 7 8 9101112131415 CREATE TABLE films (code char(5) PRIMARY KEY,title varchar(40) NOT NULL,did integer NOT NULL,date_prod date,kind varchar(10),len interval hour to minute);NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "films_pkey" for table "films"CREATE TABLEINSERT INTO films VALUES ('UA502', 'Bananas', 105, DEFAULT, 'Comedy', '82 minutes');INSERT INTO films VALUES ('UA502', 'Bananas', 105, '1971-07-13', 'Comedy', '82 minutes');ERROR: dn_6003_6004: duplicate key value violates unique constraint "films_pkey"DETAIL: Key (code)=(UA502) already exists.
  • 解决办法 为防止出现分区间隙,需要将ADD PARTITION的START值前移。 以分区表partitiontest为例: 1 2 3 4 5 6 7 8 910 CREATE TABLE partitiontest ( c_int integer, c_time TIMESTAMP WITHOUT TIME ZONE) PARTITION BY range (c_int) ( partition p1 start(100)end(108), partition p2 start(108)end(120) ); 执行如下两种语句会发生报错: 12 ALTER TABLE partitiontest ADD PARTITION p3 start(120)end(130), DROP PARTITION p2;ERROR: start value of partition "p3" NOT EQUAL up-boundary of last partition. 12 ALTER TABLE partitiontest DROP PARTITION p2,ADD PARTITION p3 start(120)end(130);ERROR: start value of partition "p3" NOT EQUAL up-boundary of last partition. 可以修改语句为: 1 ALTER TABLE partitiontest ADD PARTITION p3 start(108)end(130), DROP PARTITION p2; 1 ALTER TABLE partitiontest DROP PARTITION p2,ADD PARTITION p3 start(108)end(130);
  • 原因分析 重新创建索引CREATE INDEX HR_staffS_p1_index2 MOVE PARTITION staff_ID2_index TABLESPACE example1,提示索引已存在,然后执行以下SQL命令或者gsql客户端元命令\d+ HR.staffS_p1 查询索引时发现索引已存在。 1 SELECT * FROM DBA_INDEXES WHERE index_name = HR.staffS_p1 ; 推测是当前模式是public模式,而不是hr模式,导致检索不到该索引。 使用“ALTER INDEX hr.HR_staffS_p1_index2 MOVE PARTITION staff_ID2_index TABLESPACE example1;”验证推测,发现调用成功。 接着调用ALTER SESSION SET CURRENT_SCHEMA TO hr;再次调用“ALTER INDEX HR_staffS_p1_index2 MOVE PARTITION staff_ID2_index TABLESPACE example1;”发现设置成功。
  • 问题现象 创建分区表索引HR_staffS_p1_index1,不指定索引分区的名字。 1 CREATE INDEX HR_staffS_p1_index1 ON HR.staffS_p1 (staff_ID) LOCAL; 创建分区索引HR_staffS_p1_index2,并指定索引分区的名字。 123456 CREATE INDEX HR_staffS_p1_index2 ON HR.staffS_p1 (staff_ID) LOCAL( PARTITION staff_ID1_index, PARTITION staff_ID2_index TABLESPACE example3, PARTITION staff_ID3_index TABLESPACE example4) TABLESPACE example; 修改索引分区staff_ID1_index的表空间为example1: 调用“ALTER INDEX HR_staffS_p1_index2 MOVE PARTITION staff_ID2_index TABLESPACE example1;”提示索引不存在。
  • 处理方法 使用SQL客户端工具连接数据库。 执行如下命令查看当前会话。 1 SELECT * FROM pg_stat_activity; 查询结果中的关键字段,说明如下: datname:用户会话所连接的数据库名称。 usename:连接数据库的用户名。 client_addr:连接数据库的客户端主机的IP地址。 在查询结果中,找出待删除的数据库名称及对应的客户端主机IP地址。 请根据客户端主机的IP地址排查连接数据库的机器及应用,并停止相关的连接。 1 CLEAN CONNECTION TO ALL FOR DATABASE database_name; 重新执行删除数据库的命令。 1 DROP DATABASE [ IF EXISTS ] database_name;
  • 处理方法 以上述问题现象中的“字符串类型varchar直接转换为整数型integer”报错为例,可以先将字段类型修改为decimal(任意精度型)再进行转换来处理。 具体的操作步骤如下: 假设报错表名为product,表定义如下: 1 SELECT * FROM PG_GET_TABLEDEF('product'); 将查询结果转换为整数型。 1 SELECT CAST(price AS integer) FROM product; 出现如下报错: 修改表字段的数据类型为decimal。 1 ALTER TABLE product ALTER COLUMN price TYPE decimal(10,1); 成功转换字段为整数型。 1 SELECT CAST(price AS integer) FROM product;
  • 问题现象 某表table01中存在以大小写字母组合的名称为“ColumnA”的字段,使用SELECT语句查询该字段时,提示字段不存在,报错:column "columna" does not exist。 12345 select ColumnA from table01 limit 100;ERROR: column "columna" does not existLINE 1: select columna from TABLE_01; ^CONTEXT: referenced column: columna
  • 处理方法 8.1.x及以上集群版本,通过pgxc_lock_conflicts视图查看锁冲突情况。 1 SELECT * FROM pgxc_lock_conflicts; 8.0.x及之前集群版本,执行以下SQL查询查看是否有阻塞的SQL语句。 1 2 3 4 5 6 7 8 91011 SELECT w.query as waiting_query,w.pid as w_pid,w.usename as w_user,l.query as locking_query,l.pid as l_pid,l.usename as l_user,n.nspname || '.' || c.relname as tablenamefrom pg_stat_activity w join pg_locks l1 on w.pid = l1.pidand not l1.granted join pg_locks l2 on l1.relation = l2.relationand l2.granted join pg_stat_activity l on l2.pid = l.pid join pg_class c on c.oid = l1.relation join pg_namespace n on n.oid=c.relnamespacewhere w.waiting; 查询到阻塞的表及模式信息后,请根据实际查询语句ID结束会话: 1 SELECT pgxc_terminate_query(7233906901463861); 或 1 EXECUTE DIRECT ON(cn_5002) 'SELECT pg_terminate_backend(139666091022080)'; 这种情况一般是因为业务调度不太合理,建议合理安排各个业务的调度时间。 还可以通过设置GUC参数lockwait_timeout,控制单个锁的最长等待时间,即单个锁的等待超时时间。 lockwait_timeout单位为毫秒(ms),默认值为20分钟。 lockwait_timeout参数属于SUSET类型参数,请参考设置GUC参数中对应的设置方法进行设置。
  • 处理方法 使用系统管理员dbadmin用户连接数据库,执行以下SQL语句查看系统时间。 1 SELECT now(); 查询结果显示当前DWS默认显示的系统时间是UTC时间,即北京时间-8H。 执行以下SQL语句查询客户端连接情况。其中, username请替换为实际被锁的用户名。 时间段,请根据实际时间修改。例如要查北京时间当天上午9点到10点这个时间段的连接情况,需由北京时间转为UTC时间,即-8H,则UTC时间为当天上午1点到2点的时间段。 1 SELECT * FROM pgxc_query_audit('2022-10-27 01:00:00','2022-10-27 02:00:00') where username='username'; 查询结果显示:IP地址为x.x.x.x的客户端一直使用错误的密码进行连接。 根据实际业务情况选择以下对应的处理办法: 如果确认步骤2查询到的IP地址是某个作业,可以先停止该作业连接,再通过系统管理员dbadmin连接数据库后,使用以下SQL语句解锁该用户。然后调整该作业设置,使用正确的密码进行连接。 1 ALTER USER username ACCOUNT UNLOCK; 如果不确认该IP地址是哪个作业,可以先参见设置尝试登录失败次数将参数failed_login_attempts修改为0,然后使用以下SQL语句重置一个新密码,此时正在连接的其他作业即使再次输错10次密码也不会被锁定。 ALTER USER username IDENTIFIED BY '{Password}'; failed_login_attempts修改为0的方式仅为临时解决方案,为保证数据库安全,不建议failed_login_attempts设置为0。建议后续定位到对应作业后,尽快将作业的连接设置调整为正确密码,继续将failed_login_attempts设置为10。
  • 原因分析 DWS数据库默认情况下,在连续输入错误密码10次后会锁定该用户(允许输入的错误次数由GUC参数failed_login_attempts(默认值为10)控制,可以参见设置尝试登录失败次数登录DWS管理控制台进行修改)。 当用户重置密码后,重试还是被锁,说明在重置后,有其他用户或者应用又用错误的密码再次尝试连接了10次或failed_login_attempts的设置值,再次导致了用户被锁。
  • 原因分析 MySQL5.0.3之前varchar(n)这里的n表示字节数。 MySQL5.0.3之后varchar(n)这里的n表示字符数,比如varchar(200),不管是英文还是中文都可以存放200个。 GaussDB (DWS)的varchar(n)这里的n表示字节数。 根据字符集,字符类型如果为gbk,每个字符占用2个字节;字符类型如果为utf8,每个字符最多占用3个字节。根据转换规则,同样的字段长度,会导致GaussDB(DWS)出现字段超长的问题。
  • 操作场景 在日常作业开发中,数据库事务管理中的锁一般指的是表级锁,GaussDB(DWS)中支持的锁模式有8种,按排他级别分别为1~8。每种锁模式都有与之相冲突的锁模式,由锁冲突表定义相关的信息,锁冲突表如表1所示。 举例:用户u1对某张表test执行INSERT事务时,此时持有RowExclusiveLock锁;此时用户u2也对test表进行VACUUM FULL事务,则该事务与INSERT事务产生锁冲突,处于锁等待状态。 常用的锁等待检测主要通过查询视图pgxc_lock_conflicts、pgxc_stat_activity、pgxc_thread_wait_status、pg_locks进行。其中pgxc_lock_conflicts视图在8.1.x版本后支持,根据集群版本号不同,检测方式不同。
  • 操作步骤 构造锁等待场景: 打开一个新的连接会话,使用普通用户u1连接GaussDB(DWS)数据库,在自己的同名SCHEMA u1下创建测试表u1.test。 1 CREATE TABLE test (id int, name varchar(50)); 开启事务1,进行INSERT操作。 12 START TRANSACTION;INSERT INTO test VALUES (1, 'lily'); 打开一个新的连接会话,使用系统管理员dbadmin连接GaussDB(DWS)数据库,执行VACUUM FULL操作,发现语句阻塞。 1 VACUUM FULL u1.test; 锁等待检测(8.1.x及以上版本) 打开一个新的连接会话,使用系统管理员dbadmin连接GaussDB(DWS)数据库,通过pgxc_lock_conflicts视图查看锁冲突情况。 如下图,回显中查看granted字段为“f”,表示VACUUM FULL语句正在等待其他锁。granted字段为“t”,表示INSERT语句是持有锁。nodename,表示锁产生在的位置,即CN或DN位置,例如cn_5001。 1 SELECT * FROM pgxc_lock_conflicts; 据语句内容确认是否中止持锁语句。如果终止,则执行以下语句。pid从1获取,cn_5001为上面查询到的nodename。 1 execute direct on (cn_5001) 'SELECT PG_TERMINATE_BACKEND(pid)'; 锁等待检测(8.0.x及以前版本) 在数据库中执行以下语句,获取VACUUM FULL操作对应的query_id。 1 SELECT * FROM pgxc_stat_activity WHERE query LIKE '%vacuum%'AND waiting = 't'; 根据获取的query_id,执行以下语句查看是否存在锁等待,并获取对应的tid。其中,{query_id}从1获取。 1 SELECT * FROM pgxc_thread_wait_status WHERE query_id = {query_id}; 回显中“wait_status”存在“acquire lock”表示存在锁等待。同时查看“node_name”显示在对应的CN或DN上存在锁等待,记录相应的CN或DN名称,例如cn_5001或dn_600x_600y。 执行以下语句,到等锁的对应CN或DN上通过查询pg_locks系统表查看VACUUM FULL操作在等待哪个锁。以下以cn_5001为例,如果在DN上等锁,则改为相应的DN名称。pid为2获取的tid。 回显中记录relation的值。 1 execute direct on (cn_5001) 'SELECT * FROM pg_locks WHERE pid = {tid} AND granted = ''f'''; 根据获取的relation,通过查询pg_locks系统表查看当前持有锁的pid。{relation}从3获取。 1 execute direct on (cn_5001) 'SELECT * FROM pg_locks WHERE relation = {relation} AND granted = ''t'''; 根据pid,执行以下语句,查到对应的SQL语句。{pid}从4获取。 1 execute direct on (cn_5001) 'SELECT query FROM pg_stat_activity WHERE pid={pid}'; 根据语句内容确认是中止持锁语句还是待持锁语句结束再重新执行VACUUM FULL。如果终止,则执行以下语句。pid从4获取。 中止结束后,再尝试重新执行VACUUM FULL。 1 execute direct on (cn_5001) 'SELECT PG_TERMINATE_BACKEND(pid)';
  • 处理方法 通过Function的exception方式屏蔽该报错,将大小统一到一个值,对于不存在的表,可以用大小为-1来表示,函数如下: 1 2 3 4 5 6 7 8 9101112131415161718 CREATE OR REPLACE FUNCTION public.pg_t_size(tab_oid OID,OUT retrun_code text) RETURNS text LANGUAGE plpgsql AS $$ DECLARE v_sql text; ts text; BEGIN V_SQL:='select pg_size_pretty(pg_table_size('||tab_oid||'))'; EXECUTE IMMEDIATE V_SQL into ts; IF ts IS NULL THEN RETRUN_CODE:=-1; ELSE return ts; END IF; EXCEPTION WHEN OTHERS THEN RETRUN_CODE:=-1; END$$; 执行如下命令查询结果: 1 2 3 4 5 6 7 8 9101112131415161718 call public.pg_t_size('1',''); retrun_code------------- -1(1 row)select oid from pg_class limit 2; oid------ 2662 2659(2 rows)call public.pg_t_size('2662',''); retrun_code------------- 120 KB(1 row)
  • 原因分析 上述问题中撤销user3对表t1的访问权限未生效是因为:之前执行过GRANT SELECT ON table t1 TO public;这条SQL语句,该语句中关键字public表示该权限要赋予给所有角色,包括之后新创建的角色,所以新用户user3对该表也有访问权限。public可以看做是一个隐含定义好的组,它包含所有角色。 因此,执行完REVOKE SELECT ON table t1 FROM user3;之后,虽然user3用户没有了表t1的访问权限(通过系统表pg_class的relacl字段可查看t1表的权限),但是他仍然有public的权限,所以仍能访问该表。
  • 处理方法 可登录GaussDB(DWS)管理控制台,设置session_timeout为0或预期时长,使会话保持长时间连接。 登录GaussDB(DWS)管理控制台。在集群列表中找到所需要的集群,单击集群名称,进入“集群详情”页面。 单击“参数修改”页签,修改session_timeout参数值,然后单击“保存”。 COPY导入执行完成后,建议继续设置session_timeout=10min,因为如果有客户端长时间连接数据库,但对数据库不进行任何操作,该连接将一直占用一个线程,如果这样的客户端连接很多,就会出现大量的线程都被空闲的连接占用,从而导致数据库连接满或者资源浪费。
  • 处理方法 方法一 该处理方法仅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;
  • 处理方法 方法一:分布键目前暂不支持更新,直接跳过该报错。 方法二:将分布列修改为一个不会更新的列(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;
  • 问题现象 数据库中新建一张表,某个表字段使用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);
  • 区域支持 区域支持指的是应用遵守文化偏好的问题,包括字母表、排序、数字格式等。区域是在使用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操作,则不能修改为复制表。
共99303条