华为云用户手册

  • 开启安全认证 登录微服务引擎控制台。 在左侧导航栏选择“ServiceComb引擎专享版”。 单击待操作的引擎。 在“网络配置 & 安全”区域,单击“开启安全认证”。 如果引擎版本低于1.2.0,执行5。 如果引擎版本为1.2.0及以上版本,执行6。 升级引擎至1.2.0或以上版本。 单击“升级”。 选择“升级后版本”,查看版本说明,根据需要决定是否升级到该版本后,单击“确定”。 在刚升级成功的ServiceComb引擎的“网络配置 & 安全”区域,单击“开启安全认证”。 在“系统管理”页面开启安全认证。 首次开启安全认证,单击“去开启安全认证”。 需先创建root账号。输入root账号的“密码”和“确认密码”,单击“立即创建”。 再次开启安全认证,输入引擎中已关联了admin角色的账号名称及其密码。 (可选)参考角色管理,根据业务需要,创建角色。 (可选)参考账号管理,根据业务需要,创建账号。 在“系统管理”页面单击“设置安全认证”,根据实际业务需要设置安全配置。 选择开启“控制台安全认证”,请执行11。 开启控制台安全认证后,进入微服务引擎控制台界面,需要使用账号、密码登录。登录账号用户只能查看、配置有权限的服务。 选择开启“编程接口安全认证”,请执行10。 开启编程接口安全认证,会自动同步开启“控制台安全认证”。 开启编程接口安全认证后,需要在微服务的配置文件中添加对应用户的账号密码,否则服务无法注册到引擎。 关闭编程接口安全认证,微服务的配置文件中无需配置账号密码即可将服务注册到引擎,效率性能更高,建议用于VPC内访问时使用。 配置SDK,对于已部署但未配置安全认证参数的微服务组件,请参考配置微服务安全认证的账号名和密码 先为组件配置微服务安全认证的账号名和密码,再升级组件。 单击“确定”。 等待ServiceComb引擎更新完成,引擎状态由“配置中”变为“可用”,开启安全认证成功。
  • 操作步骤 登录微服务引擎控制台。 在左侧导航栏选择“应用网关 ”。 单击待查看的实例的名称,进入该实例的基本信息页面。 在“基础信息”区域的“标签”参数处,您可以根据实际需要,执行以下操作: 新增标签 新增标签会影响网关业务十秒左右,请在业务低峰期时增加。 单击“标签管理”,弹出“编辑标签”窗口。 单击“ 新增标签”,您可在输入框中分别输入标签键和标签值。 单击“确定”,为实例添加标签成功。 修改标签 修改标签会影响网关业务十秒左右,请在业务低峰期时修改。 单击“标签管理”,弹出“编辑标签”窗口。 您可在原有的标签键和标签值输入框中修改标签键与标签值信息。 单击“确定”,标签修改成功。 删除标签 单击标签所在行的,删除该标签。
  • AstroPro权限 默认情况下,新建的 IAM 用户没有任何权限,需要将其加入用户组,并给用户组授予策略或角色,才能使得用户组中的用户获得对应的权限,这一过程称为授权。授权后,用户就可以基于被授予的权限对云服务进行操作。 AstroPro部署时通过物理区域划分,为项目级服务。授权时,“作用范围”需要选择“区域级项目”,然后在指定区域(如华北-北京4)对应的项目(cn-north-4)中设置相关权限,并且该权限仅对此项目生效。如果在“所有项目”中设置权限,则该权限在所有区域项目中都生效。访问AstroPro时,需要先切换至授权区域。 根据授权精细程度分为角色和策略。 角色:IAM最初提供的一种根据用户的工作职能,定义权限的粗粒度授权机制。该机制以服务为粒度,提供有限的服务相关角色用于授权。由于华为云各服务之间存在业务依赖关系,因此给用户授予角色时,可能需要一并授予依赖的其他角色,才能正确完成业务。角色并不能满足用户对精细化授权的要求,无法完全达到企业对权限最小化的安全管控要求。 策略:IAM最新提供的一种细粒度授权的能力,可以精确到具体服务的操作、资源以及请求条件等。基于策略的授权是一种更加灵活的授权方式,能够满足企业对权限最小化的安全管控要求。 如表1所示,包括了AstroPro的所有系统权限。 表1 AstroPro系统权限 策略名称 描述 类别 策略内容 Astro Pro FullAccess AstroPro服务所有权限。 系统策略 Astro Pro FullAccess策略内容 Astro Pro InstanceManagement AstroPro服务应用实例操作、管理权限。 系统策略 Astro Pro InstanceManagement策略内容 表2列出了AstroPro常用操作与系统策略的授权关系,您可以参照该表选择合适的系统策略。 表2 AstroPro操作与系统策略关系 操作 Astro Pro FullAccess Astro Pro InstanceManagement 查询商品可售卖周期 √ √ 查询订单信息 √ √ 订购询价 √ √ 查询实例信息 √ √ 变更询价 √ √ 云服务到期查询 √ √ 购买实例 √ √ 购买扩容包 √ √ 实例升级 √ √ 实例冻结 √ √ 实例解冻 √ √ 删除实例 √ √
  • Astro Pro InstanceManagement策略内容 { "Version": "1.1", "Statement": [ { "Action": [ "astropro:instance:*" ], "Effect": "Allow" } ] }
  • 环境要求 Web SDK运行环境要求,如表1所示。 表1 环境要求 环境项 使用限制 开发工具 Microsoft Visual Studio Code、WebStorm或其他Web IDE开发工具。 语言 Javascript或Typescript。 编译环境 建议Node 17+。 浏览器 浏览器使用限制,请参见表2。 由于浏览器的安全策略限制,仅支持通过“https://域名”方式访问,否则无法获取麦克风权限。 表2 浏览器适配详情 操作系统类型 浏览器类型 浏览器版本 Windows Chrome浏览器 91+ Edge浏览器 80+ Android 微信内嵌浏览器(TBS内核) - 微信内嵌浏览器(XWEB内核) - 企业微信内嵌浏览器 - 移动版Chrome浏览器 91+ iOS 微信内嵌浏览器 iOS 14.3+ 微信6.5+版本 移动版Safari浏览器 -
  • 删除Pod 删除pod时,Kubernetes终止Pod中所有容器。 Kubernetes向进程发送SIGTERM信号并等待一定的秒数(默认为30)让容器正常关闭。 如果它没有在这个时间内关闭,Kubernetes会发送一个SIGKILL信号杀死该进程。 Pod的停止与删除有多种方法,比如按名称删除,如下所示。 $ kubectl delete po nginx -n $namespace_name pod "nginx" deleted 同时删除多个Pod。 $ kubectl delete po pod1 pod2 -n $namespace_name 删除所有Pod。 $ kubectl delete po --all -n $namespace_name pod "nginx" deleted 根据Label删除Pod,Label详细内容将会在下一个章节介绍。 $ kubectl delete po -l app=nginx -n $namespace_name pod "nginx" deleted
  • 什么是Pod Pod是Kubernetes创建或部署的最小单位。一个Pod封装一个或多个容器(container)、存储资源(volume)、一个独立的网络IP以及管理控制容器运行方式的策略选项。 Pod使用主要分为两种方式: Pod中运行一个容器。这是Kubernetes最常见的用法,您可以将Pod视为单个封装的容器,但是Kubernetes是直接管理Pod而不是容器。 Pod中运行多个需要耦合在一起工作、需要共享资源的容器。通常这种场景下是应用包含一个主容器和几个辅助容器(SideCar Container),如图1所示,例如主容器为一个web服务器,从一个固定目录下对外提供文件服务,而辅助的容器周期性的从外部下载文件存到这个固定目录下。 图1 Pod 实际使用中很少直接创建Pod,而是使用Kubernetes中称为Controller的抽象层来管理Pod实例,例如Deployment和Job。Controller可以创建和管理多个Pod,提供副本管理、滚动升级和自愈能力。通常,Controller会使用Pod Template来创建相应的Pod。
  • 查询Pod详情 Pod创建完成后,可以使用kubectl get pods命令查询Pod的状态,如下所示。 $ kubectl get pods -n $namespace_name NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 40s 可以看到此处nginx这个Pod的状态为Running,表示正在运行;READY为1/1,表示这个Pod中有1个容器,其中1个容器的状态为Ready。 可以使用kubectl get命令查询具体Pod的配置信息,如下所示,-o yaml表示以YAML格式返回,还可以使用 -o json,以JSON格式返回。 $ kubectl get pod nginx -o yaml -n $namespace_name 您还可以使用kubectl describe命令查看Pod的详情。 $ kubectl describe pod nginx -n $namespace_name
  • 使用GPU 云容器实例支持使用GPU(必须在GPU类型命名空间下),申请GPU资源的方法非常简单,只需要在容器定制中申请GPU字段即可。 具体的规格信息请参考约束与限制中的“Pod规格”。 您需要设置Pod的metadata.annotations中添加cri.cci.io/gpu-driver字段,指定使用哪个版本显卡驱动,取值如下: gpu-460.106 gpu-418.126 如下示例创建一个容器规格为NVIDIA V100 16G x 1,CPU 4核,内存32GiB的Pod。 apiVersion: v1 kind: Pod metadata: name: gpu-test annotations: cri.cci.io/gpu-driver: gpu-418.126 # 指定GPU显卡的驱动版本 spec: containers: - image: tensorflow:latest name: container-0 resources: limits: cpu: 4000m # 4核 memory: 32Gi nvidia.com/gpu-tesla-v100-16GB: 1 # 申请GPU资源,支持 1、2、4、8,代表几块显卡 requests: cpu: 4000m # 4核 memory: 32Gi nvidia.com/gpu-tesla-v100-16GB: 1 imagePullSecrets: - name: imagepull-secret
  • 创建Pod kubernetes资源可以使用YAML描述(如果您对YAML格式不了解,可以参考YAML语法),也可以使用JSON,如下示例描述了一个名为nginx的Pod,这个Pod中包含一个名为container-0的容器,使用nginx:alpine镜像,使用的资源为0.5核CPU、1024M内存。 apiVersion: v1 # Kubernetes的API Version kind: Pod # Kubernetes的资源类型 metadata: name: nginx # Pod的名称 spec: # Pod的具体规格(specification) containers: - image: nginx:alpine # 使用的镜像为 nginx:alpine name: container-0 # 容器的名称 resources: # 申请容器所需的资源,云容器实例中limits与requests的值必须相同 limits: cpu: 500m # 0.5核 memory: 1024Mi requests: cpu: 500m # 0.5核 memory: 1024Mi imagePullSecrets: # 拉取镜像使用的证书,必须为imagepull-secret - name: imagepull-secret 如上面YAML的注释,YAML描述文件主要为如下部分: metadata:一些名称/标签/namespace等信息 spec:Pod实际的配置信息,包括使用什么镜像,volume等 如果去查询Kubernetes的资源,您会看到还有一个status字段,status描述kubernetes资源的实际状态,创建时不需要配置。这个示例是一个最小集,其他参数定义后面会逐步介绍。 kubernetes资源的参数定义的解释,您可以通过具体资源的API参考查询对应的解释。 Pod定义好后就可以使用kubectl创建,如果上面YAML文件名称为nginx.yaml,则创建命令如下所示,-f 表示使用文件方式创建。 $ kubectl create -f nginx.yaml -n $namespace_name pod/nginx created
  • 处理方法 方法一 该处理方法仅8.1.3及以上集群版本支持。 登录 GaussDB (DWS) 管理控制台。 在集群列表中单击指定集群名称。 进入“集群详情”页面,切换至“智能运维”页签。 在运维详情部分切换至运维计划模块。单击“添加运维任务”按钮。 弹出添加运维任务边栏。 运维任务选择“Vacuum”。 调度模式选择“指定目标”,智能运维将在指定时间窗内,自动下发表级Vacuum任务。 用户可配置需要Vacuum的列存表,其中一行对应一张表,每张表以数据库名、模式名、表名表示,以空格进行分割。 单击“下一步:定时配置”,配置Vacuum类型,推荐选择“周期型任务”,GaussDB(DWS)将自动在自定义时间窗内执行Vacuum。 确认无误后,单击“下一步:配置确认”,完成配置。 方法二 对列存表更新操作后,需要进行VACUUM FULL清理,更多用法请参见VACUUM的“VACUUM”章节的“VACUUM”章节。 1 VACUUM FULL table_name;
  • 原因分析 SQL运行慢可从以下几方面进行分析: 使用EXPLAIN命令查看SQL执行计划,根据执行计划判断是否需要进行SQL调优。 分析查询是否被阻塞,导致语句运行时间过长,可以强制结束有问题的会话。 审视和修改表定义。选择合适的分布列,避免数据倾斜。 分析SQL语句是否使用了不下推的函数,建议更换为支持下推的语法或函数。 对表定期执行vacuum full和analyze操作,可回收已更新或已删除的数据所占据的磁盘空间。 检查表有无索引支撑,建议例行重建索引。 数据库经过多次删除操作后,索引页面上的索引键将被删除,造成索引膨胀。例行重建索引,可有效的提高查询效率。 对业务进行优化,分析能否将大表进行分表设计。
  • 排查方法 查看相关表CU中数据分布情况,以下操作在DN执行 查看列存表对应的cudesc表 针对非分区表: 1 SELECT 'cstore.'||relname FROM pg_class where oid = (SELECT relcudescrelid FROM pg_class c inner join pg_namespace n on c.relnamespace = n.oid where relname = 'table name' and nspname = 'schema name'); 针对分区表: 1 SELECT 'cstore.'||relname FROM pg_class where oid in (SELECT p.relcudescrelid FROM pg_partition p,pg_class c,pg_namespace n where c.relnamespace = n.oid and p.parentid = c.oid and c.relname = 'table name' and n.nspname = 'schema name' and p.relcudescrelid != 0); 查看cudesc中各CU的rowcount情况 查询步骤一返回的cudesc表信息,查询结果类似如下,主要关注row_count过小(远小于6w)的CU数量,如果此数量较大,说明当前小CU多,CU膨胀问题严重,影响存储效率和查询访问效率。
  • 原因分析 两个不同的事务对同一个表中的同一行数据进行并发更新/操作,导致后操作的事务发生了回滚。 举例说明: 打开一个连接Session A,使用普通用户u1连接GaussDB(DWS)数据库,在u1的同名SCHEMA u1下创建测试表u1.test,并插入数据。 1 2 CREATE TABLE test (id int, name varchar(50)); INSERT INTO test VALUES (1, 'lily'); 打开一个新的连接会话Session B,使用系统管理员dbadmin连接GaussDB(DWS)数据库,开启事物1,执行UPDATE操作,UPDATE语句执行成功。 1 2 3 4 START TRANSACTION; UPDATE u1.test SET id = 3 WHERE name = 'lily'; UPDATE 1 在会话Session A中开启事务2,执行相同的UPDATE语句,执行报错。 1 2 3 4 START TRANSACTION; UPDATE test SET id = 3 WHERE name = 'lily'; ERROR: dn_6003_6004: abort transaction due to concurrent update test 289502. 针对上述案例,两个不同的事务并发更新了同一条记录,而并发更新同一条记录发生冲突不会等待锁,直接报错:abort transaction due to concurrent update。 在实际业务中,并不是只有并发UPDATE同一条记录会报错,select、delete等其他SQL并发操作,也有可能报错:abort transaction due to concurrent update。
  • 原因分析 上述问题中撤销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的权限,所以仍能访问该表。
  • 调用存储过程报错 ERROR: cached plan must not change result type 问题分析:由于JDBC中使用了PreparedStatement,默认重复执行5次就会缓存plan,在此之后有如果重建表操作(例如修改表定义),再次执行就会报错ERROR: cached plan must not change result type。 处理方法:在JDBC连接字串中指定prepareThreshold=0,不再cache plan。例如: 1 String url = "jdbc:postgresql:// 192.168.0.10:2000/postgres?prepareThreshold=0";
  • 使用JDBC执行create table as 语句报错 ERROR: relation "xx" already exists 问题分析:JDBC调用preparedStatement.getParameterMetaData()时会发送P报文,该报文会在数据库中创建表,导致execute执行时报表已存在。 处理方法:使用preparedStatement时,建议将CREATE TABLE AS拆开执行或者使用resultSet.getMetaData()。
  • Broken pipe, connection reset by peer 问题分析:网络故障,数据库连接超时。 处理方法:检查网络状态,修复网络故障,影响数据库连接超时的因素,例如数据库参数session_timeout。 登录控制台单击指定集群名称。 在左侧导航栏选择“参数修改”,搜索参数“session_timeout”查看超时时间参数。 将session_timeout的CN、DN参数值设置为0,详情可参见修改数据库参数。
  • 处理方法 方式一:通过控制台修改statement_timeout参数。 登录GaussDB(DWS) 管理控制台。 在左侧导航栏中,单击“集群管理”。 在集群列表中找到所需要的集群,单击集群名称,进入集群“基本信息”页面。 单击“参数修改”页签,根据需要修改参数“statement_timeout”默认值,然后单击“保存”。 GaussDB(DWS)默认不限制SQL超时,即statement_timeout默认值为0。如用户手动修改过该参数,建议恢复原默认值0,或者根据需要调整SQL超时时间,避免设置的SQL超时时间对其它任务产生影响。 在“修改预览”窗口,确认修改无误后,单击“保存”。 参数“statement_timeout”所在行“是否重启”列显示为“否”,表示该参数修改后无需进行重启操作,即修改后立即生效。 图1 修改参数statement_timeout 方式二:成功连接集群后,通过SQL命令修改statement_timeout参数。 使用SET语句修改(会话级别): 1 SET statement_timeout TO 0; 使用ALTER ROLE语句修改(用户级别): 1 ALTER USER username SET statement_timeout TO 600000; 其中,username为要设置SQL语句超时时间的数据库用户名。
  • 处理方法 方法一:更改某个GaussDB(DWS) 集群的数据库默认时区。 登录GaussDB(DWS) 管理控制台。 在左侧导航栏中,单击“集群管理”。 在集群列表中找到所需要的集群,单击集群名称,进入集群“基本信息”页面。 单击“参数修改”页签,修改参数“timezone”,修改为您所在的时区,然后单击“保存”。 在“修改预览”窗口,确认修改无误后,单击“保存”。 用户可根据界面中参数“timezone”所在行的“是否重启”列,判断修改参数后无需进行重启操作。 修改“timezone”参数后无需重启集群操作 ,则修改后立即生效。 方法二:通过后台命令查询和更改数据库时区。 查询客户端时区和当前时间。其中客户端时区为UTC时区,now()函数返回当前时间。 1 2 3 4 5 6 7 8 9 10 11 show time zone; TimeZone ---------- UTC (1 row) select now(); now ------------------------------- 2022-05-16 06:05:58.711454+00 (1 row) 创建数据表,其中timestamp,timestamptz是常用的时间类型。timestamp不保存时区,timestamptz保存时区。 1 2 3 4 5 6 7 8 9 CREATE TABLE timezone_test (id int, t1 timestamp, t2 timestamptz) DISTRIBUTE BY HASH (id); \d timezone_test Table "public.timezone_test" Column | Type | Modifiers --------+-----------------------------+----------- id | integer | t1 | timestamp without time zone | t2 | timestamp with time zone | 向timezone_test表插入当前时间并查询当前表。 1 2 3 4 5 6 7 8 9 10 11 insert into timezone_test values (1, now(), now() ); show time zone; TimeZone ---------- UTC (1 row) select * from timezone_test; id | t1 | t2 ----+----------------------------+------------------------------- 1 | 2022-05-16 06:10:04.564599 | 2022-05-16 06:10:04.564599+00 (1 row) t1 (timestamp类型)在保存数据时丢弃了时区信息,t2(timestamptz类型)保存了时区信息。 把客户端时区设置为东8区(UTC-8),再次查询timezone_test表。 1 2 3 4 5 6 7 8 9 10 11 set time zone 'UTC-8'; show time zone; TimeZone ---------- UTC-8 (1 row) select now(); now ------------------------------- 2022-05-16 14:13:43.175416+08 (1 row) 继续插入当前时间到timezone_test表,并查询。 此时t1新插入的值是用的东8区时间,t2根据客户端时区对查询结果进行转换。 1 2 3 4 5 6 7 insert into timezone_test values (2, now(), now() ); select * from timezone_test; id | t1 | t2 ----+----------------------------+------------------------------- 1 | 2022-05-16 06:10:04.564599 | 2022-05-16 14:10:04.564599+08 2 | 2022-05-16 14:15:03.715265 | 2022-05-16 14:15:03.715265+08 (2 rows) timestamp类型只受数据在插入时的时区影响,查询结果不受客户端时区影响。 timestamptz类型在数据插入时记录了时区信息,查询时会根据客户端时区做转换,以客户端时区显示数据。
  • 解决方案 建议根据业务实际情况调整update语句。比如分析public.t2的字段含义,确定更新的目标字段。针对上述案例,如果期望在a值相等的情况下,把public.t1中字段b更新为public.t2中的最大值,那么可以修改为如下逻辑: 1 2 3 4 5 6 7 UPDATE t1 SET t1.b = t2.b_max FROM (SELECT a, max(b) AS b_max FROM t2 GROUP BY a) t2 WHERE t1.a = t2.a; UPDATE 1 SELECT * FROM public.t1; a | b ---+--- 1 | 2 (1 row)
  • 原因分析 当一条SQL语句中同一个元组被多次更新,执行便会报错ERROR:Non-deterministic UPDATE。 可以看到更新操作分成两步执行: 通过关联操作查找满足更新条件的元组。 执行更新操作。 针对上述案例,对于表public.t1中元组 (1, 1)来说,表public.t2中满足更新条件t1.a = t2.a的记录有两条,分别为(1, 1), (1, 2);按照执行器逻辑表t2的元组 (1, 1)需要被更新两次,那么就可能出现两种情况: 表public.t1和表public.t2关联时先命中(1, 1),再命中(1, 2),这时public.t1的元组(1, 1),先被更新为(1,1),再被更新为(1,2),最终结果为(1, 2)。 表public.t1和表public.t2关联时先命中(1, 2),再命中(1, 1),这时public.t1的元组(1, 1),先被更新为(1,2),再被更新为(1,1),最终结果为(1, 1)。 实际执行过程中public.t2表输出结果集的顺序会影响update语句的最终输出结果(实际业务中表public.t2的位置可能是一个非常复杂的子查询),导致了update语句执行结果的随机性,而这个实际业务中是无法接受的。
  • 问题现象 执行update语句报错ERROR:Non-deterministic UPDATE 1 2 3 4 5 6 7 8 9 10 11 12 CREATE TABLE public.t1(a int, b int) WITH(orientation = column); CREATE TABLE CREATE TABLE public.t2(a int, b int) WITH(orientation = column); CREATE TABLE INSERT INTO public.t1 VALUES (1, 1); INSERT INTO public.t2 VALUES (1, 1),(1, 2); UPDATE t1 SET t1.b = t2.b FROM t2 WHERE t1.a = t2.a; ERROR: Non-deterministic UPDATEDETAIL: multiple updates to a row by a single query for column store table.
  • 问题现象 查看日志提示: [ERROR] Mpp task queryDataAnalyseById or updateDataAnalyseHistoryEndTimesAndResult fail, dataAnalyseId:17615 org.postgresql.util.PSQLException: ERROR: memory is temporarily unavailable sql:vacuum full dws_customer_360.t_user_resource;
  • 操作步骤 构造锁等待场景: 打开一个新的连接会话,使用普通用户u1连接GaussDB(DWS)数据库,在自己的同名SCHEMA u1下创建测试表u1.test。 1 CREATE TABLE test (id int, name varchar(50)); 开启事务1,进行INSERT操作。 1 2 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)';
  • 操作场景 在日常作业开发中,数据库事务管理中的锁一般指的是表级锁,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版本后支持,根据集群版本号不同,检测方式不同。
  • 原因分析 数据文件是从Oracle导入的,文件编码为utf-8。该报错还会提示行数,由于文件特别大,vim命令打不开文件,于是用sed命令把报错行数提出来,再用vim命令打开,发现并没有什么异常。用split命令按行数切割后,部分文件也可以导入。 经分析GaussDB(DWS)的varchar型的字段或变量不接受含有'\0'(也即数值0x00、UTF编码'\u0000')的字符串 ,需在导入前去掉字符串中的'\0'。
  • 在modifyJdbcCall和createParameterizedQuery阶段耗时 问题分析:如果主要耗时在modifyJdbcCall阶段(校验传入的SQL是否符合规范)和createParameterizedQuery阶段(将传入的SQL解析为preparedQuery,以获取由simplequery组成的subqueries),则需要确认是否传入的SQL过长导致。 处理方法:JDBC本身没办法优化这部分耗时,可在应用端查看是否可优化传入的SQL语句,详情可参见SQL语句改写规则。
  • JDBC问题定位 JDBC(Java Database Connectivity,java数据库连接)是应用程序访问数据库的统一标准接口,应用程序可使用JDBC连接数据库并执行SQL。 GaussDB(DWS)提供了对JDBC 4.0特性的支持,本章节提供了JCDB常见问题定位及对应报错和问题的处理方法。 产生JDBC问题的原因主要是三个方面: 应用程序和应用程序框架问题。 JDBC业务功能问题。 数据库配置问题。 JDBC问题在具体业务中的表现可以分为三个大的方面: 执行报错,JDBC抛出异常。 执行效率低,耗时异常。 特性不支持,JDBC未实现的JDK接口。 JDBC问题具体分类可参见表1。 表1 JDBC问题分类 问题分类 问题原因 建立数据库连接失败 JDBC客户端配置问题:包括URL格式不对,或用户名密码错误。 网络不通。 Jar包冲突。 数据库配置问题,数据库未配置远程访问权限。 执行业务抛出异常 传入SQL有误,GaussDB(DWS)不支持。 业务处理异常,返回异常报文。 网络故障。 数据库连接超时,socket已关闭。 性能问题 SQL执行慢。 结果集过大,导致应用程序段响应慢。 用户传入SQL过长,JDBC解析慢。 功能支持问题 JDK未提供标准接口。 JDBC未实现接口。 父主题: JDBC/ODBC类
  • 处理方法 使用SQL客户端工具连接数据库。 执行如下命令查看当前会话。 1 SELECT * FROM pg_stat_activity; 查询结果中的关键字段,说明如下: datname:用户会话所连接的数据库名称。 usename:连接数据库的用户名。 client_addr:连接数据库的客户端主机的IP地址。 在查询结果中,找出待删除的数据库名称及对应的客户端主机IP地址。 请根据客户端主机的IP地址排查连接数据库的机器及应用,并停止相关的连接。 1 CLEAN CONNECTION TO ALL FOR DATABASE xxx; 重新执行删除数据库的命令。 1 DROP DATABASE [ IF EXISTS ] database_name;
共100000条