华为云用户手册

  • 场景介绍 在业务场景中,普通用户创建的表,系统管理员dbadmin默认是有访问权限,并未完全私有。而在三权分立开启下的业务场景中,管理员dbadmin对普通用户的表没有访问权限,同时也没有控制权限(DROP、ALTER、TRUNCATE)。 若当前业务中需要创建一个私有用户和私有表(即私有用户创建的表),私有表只有私有用户本身可以访问,系统管理员dbadmin和其他普通用户均无权访问(进行INSERT、DELETE、UPDATE、SELECT、COPY操作),但同时需要满足:未经私有用户授权的情况下,可允许系统管理员dbadmin执行DROP/ALTER/TRUNCATE操作。那么可以通过创建INDEPENDENT属性的用户(私有用户)实现。 图1 私有用户
  • 操作步骤 使用系统管理员dbadmin连接DWS数据库。 执行以下SQL语句创建私有用户u1。 1 CREATE USER u1 WITH INDEPENDENT IDENTIFIED BY 'password'; 切换到u1用户,创建测试表test,并插入数据。 1 2 3 CREATE TABLE test (id INT, name VARCHAR(20)); INSERT INTO test VALUES (1, 'joe'); INSERT INTO test VALUES (2, 'jim'); 切换到dbadmin用户,并执行以下SQL语句验证dbadmin用户是否可以访问私有用户u1创建的私有表test。 1 SELECT * FROM u1.test; 查询结果提示dbadmin无权访问,即私有用户和私有表创建成功。 dbadmin用户执行DROP语句,可成功删除test表。 1 DROP TABLE u1.test;
  • 实现原理 通过创建INDEPENDENT属性的用户来实现。 INDEPENDENT | NOINDEPENDENT 定义私有、独立的角色。具有INDEPENDENT属性的角色,管理员对其进行的控制、访问的权限被分离,具体规则如下: 未经INDEPENDENT角色授权,管理员无权对其表对象进行增、删、查、改、拷贝、授权操作。 未经INDEPENDENT角色授权,管理员无权修改INDEPENDENT角色的继承关系。 管理员无权修改INDEPENDENT角色的表对象的属主。 管理员无权修改INDEPENDENT角色的数据库口令,INDEPENDENT角色需管理好自身口令,口令丢失无法重置。 管理员属性用户不允许定义修改为INDEPENDENT属性。
  • 如何使用 使用华为云账户登录GaussDB(DWS)管理控制台。 在页面右上角单击“小D助手”进入智能问答页面。 参见表1进行询问。 表1 问题样例 场景 问题样例 产品咨询、购买 DWS怎么购买 DWS的功能有什么 查大功能、大场景、规格、大特性的介绍 DWS支持哪些导入方式 怎么导入数据 在线扩容 并发连接数多大 支持的分区表的大小 某个特性是否支持,某个SQL语法的具体使用 DWS支持roundrobin吗 list分区是否支持 是否支持磁盘扩容 create table 如何给某个shema下的对象授权 主键如何使用 查询表占用的总大小 建表字段是date,为啥建完是timestamp 开发过程遇到问题、错误码查询 创建外表失败,提示OBS访问被拒绝 账号锁住了,如何解锁 赋予用户schema的all权限后建表仍然报错:ERROR: current user does not have privilege to role tom GAUSS-00051 memory is temporarily unavailable 解决方案 资源负载管理最佳实践 GDS实践指南 SQL查询最佳实践
  • 函数和存储过程有什么区别? 函数和存储过程是数据库管理系统中常见的两种对象,它们在实现特定功能时具有相同点,也有不同点。了解它们的特点和适用场景,对于合理设计数据库结构和提高数据库性能具有重要意义。 表1 函数和存储过程的区别 函数 存储过程 两者都可以用于实现特定的功能。无论是函数还是存储过程,都可以封装一系列的SQL语句,以完成某些特定的操作。 两者都可以接收输入参数,并且根据参数的不同来进行相应的操作。 函数的标识符为FUNCTION。 存储过程的标识符为PROCEDURE。 函数必须返回一个具体的值,并且规定返回值的数值类型。 存储过程可以没有返回值,也可以有返回值,甚至可以有多个返回值,可以通过输出参数返回结果,也可以直接在存储过程中使用SELECT语句返回结果集。 函数适用于需要返回单个值的情况,比如计算某个数值、字符串处理、返回表等。 存储过程适用于需要执行DML操作的情况,比如批量插入、更新、删除数据等。 创建并调用函数 创建表emp并插入数据,查询表数据如下: 1 2 3 4 5 6 7 8 SELECT * FROM emp; empno | ename | job | mgr | hiredate | sal | comm | deptno -------+-------+----------+------+---------------------+---------+--------+-------- 7369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | | 20 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 | 30 7566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | | 20 7521 | WARD | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250.00 | 500.00 | 30 (4 rows) 创建函数emp_comp,用于接受两个数字作为输入并返回计算值: 1 2 3 4 5 6 7 8 9 CREATE OR REPLACE FUNCTION emp_comp ( p_sal NUMBER, p_comm NUMBER ) RETURN NUMBER IS BEGIN RETURN (p_sal + NVL(p_comm, 0)) * 24; END; / 使用SELECT命令调用函数: 1 2 3 4 5 6 7 8 SELECT ename "Name", sal "Salary", comm "Commission", emp_comp(sal, comm) "Total Compensation" FROM emp; Name | Salary | Commission | Total Compensation -------+---------+------------+-------------------- SMITH | 800.00 | | 19200.00 ALLEN | 1600.00 | 300.00 | 45600.00 JONES | 2975.00 | | 71400.00 WARD | 1250.00 | 500.00 | 42000.00 (4 rows) 创建并调用存储过程 创建表MATCHES并插入数据,查询表数据如下: 1 2 3 4 5 6 7 8 9 SELECT * FROM MATCHES; matchno | teamno | playerno | won | lost ---------+--------+----------+-----+------ 1 | 1 | 6 | 3 | 1 7 | 1 | 57 | 3 | 0 8 | 1 | 8 | 0 | 3 9 | 2 | 27 | 3 | 2 11 | 2 | 112 | 2 | 3 (5 rows) 创建存储过程delete_matches,用于删除给定球员参加的所有比赛: 1 2 3 4 5 6 CREATE PROCEDURE delete_matches(IN p_playerno INTEGER) AS BEGIN DELETE FROM MATCHES WHERE playerno = p_playerno; END; / 调用存储过程delete_matches: 1 CALL delete_matches(57); 再次查询表MATCHES,由返回结果可知,playerno为57的数据已被删除: 1 2 3 4 5 6 7 8 SELECT * FROM MATCHES; matchno | teamno | playerno | won | lost ---------+--------+----------+-----+------ 11 | 2 | 112 | 2 | 3 8 | 1 | 8 | 0 | 3 1 | 1 | 6 | 3 | 1 9 | 2 | 27 | 3 | 2 (4 rows) 父主题: 数据库使用
  • 如何将联结查询的null结果替换成0? 在执行outer join(left join、right join、full join)联结查询时,outer join在匹配失败的情况下结果集会补空,产生大量NULL值, 可以在联结查询时将这部分null值替换为0。 可使用coalesce函数,它的作用是返回参数列表中第一个非NULL的参数值。例如: 1 2 3 4 5 SELECT coalesce(NULL,'hello'); coalesce ---------- hello (1 row) 有表course1和表course2,使用left join对两表进行联结查询: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 SELECT * FROM course1; stu_id | stu_name | cour_name ----------+------------+-------------------- 20110103 | ALLEN | Math 20110102 | JACK | Programming Design 20110101 | MAX | Science (3 rows) SELECT * FROM course2; cour_id | cour_name | teacher_name ---------+--------------------+-------------- 1002 | Programming Design | Mark 1001 | Science | Anne (2 rows) SELECT course1.stu_name,course2.cour_id,course2.cour_name,course2.teacher_name FROM course1 LEFT JOIN course2 ON course1.cour_name = course2.cour_name ORDER BY 1; stu_name | cour_id | cour_name | teacher_name ------------+---------+--------------------+-------------- ALLEN | | | JACK | 1002 | Programming Design | Mark MAX | 1001 | Science | Anne (3 rows) 使用coalesce函数将查询结果中的空值替换为0或其他非0值: 1 2 3 4 5 6 7 8 9 10 11 12 13 SELECT course1.stu_name, coalesce(course2.cour_id,0) AS cour_id, coalesce(course2.cour_name,'NA') AS cour_name, coalesce(course2.teacher_name,'NA') AS teacher_name FROM course1 LEFT JOIN course2 ON course1.cour_name = course2.cour_name ORDER BY 1; stu_name | cour_id | cour_name | teacher_name ------------+---------+--------------------+-------------- ALLEN | 0 | NA | NA JACK | 1002 | Programming Design | Mark MAX | 1001 | Science | Anne (3 rows) 父主题: 数据库使用
  • 动态行转列 8.1.2及以上集群版本可使用GROUP_CONCAT生成列存语句。 1 2 3 4 5 6 7 8 9 10 SELECT group_concat(concat('sum(IF(subject = ''', subject, ''', score, 0)) AS "', name, '"'))FROM students_info; group_concat ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------ sum(IF(subject = 'literature', score, 0)) AS "jack",sum(IF(subject = 'literature', score, 0)) AS "lily",sum(IF(subject = 'literature', score, 0)) AS "matu",sum(IF(subject = 'math', score, 0)) AS "jack",sum(IF (subject = 'math', score, 0)) AS "lily",sum(IF(subject = 'math', score, 0)) AS "matu",sum(IF(subject = 'physics', score, 0)) AS "jack",sum(IF(subject = 'physics', score, 0)) AS "lily",sum(IF(subject = 'physics ', score, 0)) AS "matu" (1 row) 8.1.1及更低版本中可用LISTAGG生成列存语句。 1 2 3 4 5 6 7 8 SELECT listagg(concat('sum(case when subject = ''', subject, ''' then score else 0 end) AS "', subject, '"'),',') within GROUP(ORDER BY 1)FROM (select distinct subject from students_info); listagg ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- sum(case when subject = 'literature' then score else 0 end) AS "literature",sum(case when subject = 'physics' then score else 0 end) AS "physics",sum(case when subject = 'math' then score else 0 end) AS "math " (1 row) 再通过视图动态重建: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 CREATE OR REPLACE FUNCTION build_view() RETURNS VOID LANGUAGE plpgsql AS $$ DECLARE sql text; rec record; BEGIN sql := 'select LISTAGG( CONCAT( ''sum(case when subject = '''''', subject, '''''' then score else 0 end) AS "'', subject, ''"'' ) ,'','' ) within group(order by 1) from (select distinct subject from students_info);'; EXECUTE sql INTO rec; sql := 'drop view if exists get_score'; EXECUTE sql; sql := 'create view get_score as select name, ' || rec.LISTAGG || ' from students_info group by name'; EXECUTE sql; END$$; 执行重建: 1 CALL build_view(); 查询视图: 1 2 3 4 5 6 7 SELECT * FROM get_score; name | literature | physics | math ------+------------+---------+------ matu | 85 | 90 | 75 lily | 92 | 80 | 95 jack | 95 | 95 | 90 (3 rows)
  • 列转行 使用union all,将各科目(math、physics和literature)整合为一列,示例如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 SELECT * FROM ( SELECT name, 'math' AS subject, math AS score FROM students_info1 union all SELECT name, 'physics' AS subject, physics AS score FROM students_info1 union all SELECT name, 'literature' AS subject, literature AS score FROM students_info1 ) order by name; name | subject | score ------+------------+------- jack | math | 90 jack | physics | 95 jack | literature | 95 lily | math | 95 lily | physics | 80 lily | literature | 92 matu | math | 75 matu | physics | 90 matu | literature | 85 (9 rows)
  • 静态行转列 静态行转列需要手动指定每一列的列名,如果存在则取其对应值,否则将赋其默认值0。 1 2 3 4 5 6 7 8 9 10 SELECT name, sum(case when subject='math' then score else 0 end) as math, sum(case when subject='physics' then score else 0 end) as physics, sum(case when subject='literature' then score else 0 end) as literature FROM students_info GROUP BY name; name | math | physics | literature ------+------+---------+------------ matu | 75 | 90 | 85 lily | 95 | 80 | 92 jack | 90 | 95 | 95 (3 rows)
  • 示例表 创建行存表students_info并插入数据。 1 2 3 4 5 6 7 8 9 10 CREATE TABLE students_info(name varchar(20),subject varchar(100),score bigint) distribute by hash(name); INSERT INTO students_info VALUES('lily','math',95); INSERT INTO students_info VALUES('lily','physics',80); INSERT INTO students_info VALUES('lily','literature',92); INSERT INTO students_info VALUES('matu','math',75); INSERT INTO students_info VALUES('matu','physics',90); INSERT INTO students_info VALUES('matu','literature',85); INSERT INTO students_info VALUES('jack','math',90); INSERT INTO students_info VALUES('jack','physics',95); INSERT INTO students_info VALUES('jack','literature',95); 查看表students_info信息。 1 2 3 4 5 6 7 8 9 10 11 12 SELECT * FROM students_info; name | subject | score ------+------------+------- matu | math | 75 matu | physics | 90 matu | literature | 85 lily | math | 95 lily | physics | 80 lily | literature | 92 jack | math | 90 jack | physics | 95 jack | literature | 95 创建列存表students_info1并插入数据。 1 2 3 4 CREATE TABLE students_info1(name varchar(20), math bigint, physics bigint, literature bigint) with (orientation = column) distribute by hash(name); INSERT INTO students_info1 VALUES('lily',95,80,92); INSERT INTO students_info1 VALUES('matu',75,90,85); INSERT INTO students_info1 VALUES('jack',90,95,95); 查看表students_info1信息。 1 2 3 4 5 6 7 SELECT * FROM students_info1; name | math | physics | literature ------+------+---------+------------ matu | 75 | 90 | 85 lily | 95 | 80 | 92 jack | 90 | 95 | 95 (3 rows)
  • 场景介绍 以学生成绩为例: 老师会按照学科录入成绩,每科老师都会单独录入每个学生对应学科的成绩,而每位学生只关注自己各科的成绩。如果把老师录入数据作为原始表,那么学生查看自己的成绩就要用到行转列;如果让学生自己填写各科的成绩并汇总,然后老师去查自己学科所有学生的成绩,那就是列转行。 行转列与列转行的示意图如下: 图1 示意图 行转列 将多行数据转换成一行显示,或将一列数据转换成多列显示。 列转行 将一行数据转换成多行显示,或将多列数据转换成一列显示。
  • 8.1.3及以上版本 8.1.3及以上版本的集群,AUTO VACUUM默认是打开的(由GUC参数autovacuum控制),用户通过设置对应的GUC参数后,系统会自动触发所有系统表和用户的行存表进行VACUUM FULL,用户不需要手动执行vacuum。 autovacuum_max_workers = 0,系统表和普通表都不会触发。 autovacuum = off,普通表不会触发,但系统表会触发。 以上仅针对行存表的AUTO VACCUM触发,如果需要针对列存表做自动触发VACUUM,还需要用户在管理控制台上配置智能调度任务。具体参见运维计划。
  • 原因分析 若直接使用REVOKE CONNECT ON DATABASE gaussdb from u1命令撤销u1用户的权限不会生效,因为数据库的CONNECT权限授予了PUBLIC,需指定关键字PUBLIC实现。 GaussDB(DWS)提供了一个隐式定义的拥有所有角色的组PUBLIC,所有创建的用户和角色默认拥有PUBLIC所拥有的权限。要撤销或重新授予用户和角色对PUBLIC的权限,可通过在GRANT和REVOKE指定关键字PUBLIC实现。 GaussDB(DWS)会将某些类型的对象上的权限授予PUBLIC。默认情况下,对表、表字段、序列、外部数据源、外部服务器、模式或表空间对象的权限不会授予PUBLIC。以下这些对象的权限会授予PUBLIC: 数据库的CONNECT权限。 CREATE TEMP TABLE权限。 函数的EXECUTE特权。 语言和数据类型(包括域)的USAGE特权。 对象拥有者可以撤销默认授予PUBLIC的权限并专门授予权限给其他用户。
  • 数据库管理 表2 数据库管理 热度排名 高频问题 页面地址 1 查看表定义 查看DDL 查看视图结构 查询数据库和表大小 查看表和数据库的信息 2 清理表空间 VACUUM FULL 表在大量执行增删改后,如何提升查询性能 VACUUM 3 如何查看某用户在当前表上是否已有权限 查看某用户对某张表是否有某种权限 如何查看某个用户有哪些表的权限? 4 查询和终止阻塞语句 查询活跃语句 终止会话 锁等待超时 分析正在执行的SQL 5 SQL执行计划详解 执行计划怎么看 Nested Loop、Hash Join和Merge Join的差异 SQL执行计划详解 6 解除只读 数据库进入只读状态 磁盘使用率高&集群只读处理方案 7 收集统计信息 ANALYZE | ANALYSE 8 优化器配置 打开或关闭nestloop 打开或关闭mergejoin 影响执行计划的参数 优化器方法配置 9 更改数据库时区 更改Timezone 数据库时间与系统时间不一致,如何更改数据库默认时区 10 怎么查函数定义 访问权限查询函数 查询视图定义 系统信息函数 11 技术指标 支持的分区表大小 单表最大数据量 表支持的最大列数 技术指标 12 开发人员选项 控制查询优化器是否使用分布式框架 开发人员选项
  • 语法使用 表1 语法使用 热度排名 高频问题 页面地址 1 查询字符串的bit位数 截取子字符串 返回结果替换某些字符串 返回字符串的前面几个字符 过滤头尾部分字符串 获取指定字符串的字节数 字符处理函数和操作符 2 如何创建分区表 支持的分区类型 CREATE TABLE PARTITION 3 查看所有schema 查看某个schema下所有的表 Schema 4 增加表字段 修改数据类型 向表中的列添加NOT NULL约束 设置主键 修改表属性 ALTER TABLE 5 日期函数 pg_sleep()如何使用 月份相减 date类型转换函数 时间、日期处理函数和操作符 6 调整分布列 把分布列调整到另外一列 分布列的数据无法update,提示Distributed key column can't be updated in current version 如何调整分布列 7 分区管理 增加或删除分区 重命名分区 查询某个分区的数据 创建和管理分区表 8 查询某个分区的行数 合并两个分区 ALTER TABLE PARTITION 9 调用存储过程 CALL 10 创建表 create table like CREATE TABLE 11 授权命令 grant语法使用 将用户权限授权给其他用户 将表权限授权给用户 将整库权限授权给用户 外表权限 GRANT 12 REPLACE 替换函数 to_timestamp 转换为指定格式的时间戳 current_timestamp to_number 类型转换函数
  • CREATE DATABASE语法格式 1 2 3 4 5 6 7 8 CREATE DATABASE database_name [ [ WITH ] { [ OWNER [=] user_name ] | [ TEMPLATE [=] template ] | [ ENCODING [=] encoding ] | [ LC_COLLATE [=] lc_collate ] | [ LC_CTYPE [=] lc_ctype ] | [ DBCOMPATIBILITY [=] compatibility_type ] | [ CONNECTION LIMIT [=] connlimit ]}[...] ];
  • 如何查看某个用户有哪些表的权限? 场景一:查看用户有哪些表的权限,可使用information_schema.table_privileges系统表查看。例如 1 SELECT * FROM information_schema.table_privileges WHERE GRANTEE='user_name'; 表1 table_privileges字段 字段 数据类型 描述 grantor sql_identifier 赋权用户。 grantee sql_identifier 被赋权用户。 table_catalog sql_identifier 包含该表的数据库名。 table_schema sql_identifier 包含该表的模式名。 table_name sql_identifier 表名。 privilege_type character_data 被赋予的权限类型:SELECT,INSERT,UPDATE,DELETE,TRUNCATE,REFERENCES,ANALYZE,VACUUM,ALTER,DROP或TRIGGER。 is_grantable yes_or_no 权限是否可赋予其他用户,YES表示可授予,NO表示不可授予。 with_hierarchy yes_or_no 是否允许在表继承层级上的特定操作。当特定操作为SELECT时显示YES,否则为NO。 如上图所示,表示用户u2拥有Schema u2下的t2的所有权限和Schema u1下的t1的SELECT权限。 需注意,在查询有哪些表权限时,information_schema.table_privileges只能查到当前用户被直接授予的权限,而函数has_table_privilege()除了能查询被直接授予的权限外还能查到间接的权限(即GRANT role to user获取的)。例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 CREATE TABLE t1 (c1 int); CREATE USER u1 password '********'; CREATE USER u2 password '********'; GRANT dbadmin to u2; // 间接通过角色成员关系赋予权限 GRANT SELECT on t1 to u1; // 直接授予权限 SET ROLE u1 password '********'; SELECT * FROM public.t1; 直接授权可以访问表 c1 ---- (0 rows) SET ROLE u2 password '********'; SELECT * FROM public.t1; //间接授权可以访问表 c1 ---- (0 rows) RESET role; //切回到dbadmin SELECT * FROM information_schema.table_privileges WHERE table_name = 't1'; // information_schema.table_privileges仅能看到直接授权 grantor | grantee | table_catalog | table_schema | table_name | privilege_type | is_grantable | with_hierarchy ---------+------------+---------------+--------------+------------+----------------+--------------+---------------- dbadmin | u1 | gaussdb | public | t1 | SELECT | NO | YES (1 rows) SELECT has_table_privilege('u2', 'public.t1', 'select'); // has_table_privilege还可以看到间接授权 has_table_privilege --------------------- t (1 row) 场景二:查看用户是否有某张表的权限,可以通过以下方法。 执行以下语句查询pg_class系统表。 1 SELECT * FROM pg_class WHERE relname = 'tablename'; 查看relacl字段,该字段回显结果如下,权限参数参见表2。 "rolename=xxxx/yyyy" --表示rolename对该表有xxxx权限,且权限来自yyyy; "=xxxx/yyyy" -- 表示public对该表有xxxx权限,且权限来自yyyy。 例如下图: joe=arwdDxtA,表示joe用户有所有权限(ALL PRIVILEGES)。 leo=arw/joe,表示leo用户拥有读、写、改权限,该权限来自joe授权。 表2 权限的参数说明 参数 参数说明 r SELECT(读) w UPDATE(写) a INSERT(插入) d DELETE D TRUNCATE x REFERENCES t TRIGGER X EXECUTE U USAGE C CREATE c CONNECT T TEMPORARY A ANALYZE|ANALYSE arwdDxtA ALL PRIVILEGES(用于表) * 给前面权限的授权选项 如果要查某用户对某张表是否有某种权限,也可以通过访问权限查询函数has_table_privilege进行查询。 1 SELECT * FROM has_table_privilege('用户名','表名','select'); 例如,查询joe对表t1是否有查询权限。 1 SELECT * FROM has_table_privilege('joe','t1','select'); 父主题: 账户、密码、权限
  • 如何查看数据库用户的创建时间? 方式一: 在创建GaussDB(DWS)数据库用户时,如果指定了用户的生效时间(VALID BEGIN)与用户创建时间一致,且之后未修改过该用户生效时间的情况下,就可以使用视图PG_USER查看用户列表,并通过valbegin字段查看该用户的生效时间,即该用户的创建时间。 示例: 创建用户jerry指定生效时间为当前创建时间。 1 CREATE USER jerry PASSWORD 'password' VALID BEGIN '2022-05-19 10:31:56'; 通过查询视图PG_USER查看用户列表。valbegin字段显示了jerry的生效时间,即jerry的创建时间。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 SELECT * FROM PG_USER; usename | usesysid | usecreatedb | usesuper | usecatupd | userepl | passwd | valbegin | valuntil | respool | parent | spacelimit | useconfig | nodegroup | tempspacelimit | spillspacelimit ---------+----------+-------------+----------+-----------+---------+----------+------------------------+----------+--------------+--------+------------+-----------+-----------+----------------+ ----------------- Ruby | 10 | t | t | t | t | ******** | | | default_pool | 0 | | | | | dbadmin | 16393 | f | f | f | f | ******** | | | default_pool | 0 | | | | | jack | 451897 | f | f | f | f | ******** | | | default_pool | 0 | | | | | emma | 451910 | f | f | f | f | ******** | | | default_pool | 0 | | | | | jerry | 457386 | f | f | f | f | ******** | 2022-05-19 10:31:56+08 | | default_pool | 0 | | | | | (5 rows) 方式二: 通过系统表PG_AUTH_HISTORY的passwordtime字段查看用户最初的密码创建时间,即该用户的创建时间。需要有系统管理员权限才可以访问此系统表。 1 SELECT roloid, min(passwordtime) as create_time FROM pg_auth_history group by roloid order by roloid; 示例: 通过查询视图PG_USER获取用户jerry的OID为457386, 查询passwordtime字段获取到用户jerry的创建时间为2022-05-19 10:31:56。 1 2 3 4 5 6 7 8 9 SELECT roloid, min(passwordtime) as create_time FROM pg_auth_history group by roloid order by roloid; roloid | create_time --------+------------------------------- 10 | 2022-02-25 09:53:38.711785+08 16393 | 2022-02-25 09:55:17.992932+08 451897 | 2022-05-18 09:42:26.897855+08 451910 | 2022-05-18 09:46:33.152354+08 457386 | 2022-05-19 10:31:56.037706+08 (5 rows) 父主题: 通用问题
  • 如果建表时没有指定分布列,数据会怎么存储? 8.1.2及以上集群版本,可通过GUC参数default_distribution_mode来查询和设置表的默认分布方式。 如果建表时没有指定分布列,数据会以下几种场景来存储: 场景一 若建表时包含主键/唯一约束,则选取HASH分布,分布列为主键/唯一约束对应的列。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE TABLE warehouse1 ( W_WAREHOUSE_SK INTEGER PRIMARY KEY, W_WAREHOUSE_ID CHAR(16) NOT NULL, W_WAREHOUSE_NAME VARCHAR(20) ); NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "warehouse1_pkey" for table "warehouse1" CREATE TABLE SELECT getdistributekey('warehouse1'); getdistributekey ------------------ w_warehouse_sk (1 row) 场景二 若建表时不包含主键/唯一约束,但存在数据类型支持作分布列的列,则选取HASH分布,分布列为第一个数据类型支持作分布列的列。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 CREATE TABLE warehouse2 ( W_WAREHOUSE_SK INTEGER , W_WAREHOUSE_ID CHAR(16) NOT NULL, W_WAREHOUSE_NAME VARCHAR(20) ); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'w_warehouse_sk' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE SELECT getdistributekey('warehouse2'); getdistributekey ------------------ w_warehouse_sk (1 row) 场景三 若建表时不包含主键/唯一约束,也不存在数据类型支持作分布列的列,选取ROUNDROBIN分布。 CREATE TABLE warehouse3 ( W_WAREHOUSE_ID CHAR(16) NOT NULL, W_WAREHOUSE_NAME VARCHAR(20) ); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'w_warehouse_id' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE SELECT getdistributekey('warehouse3'); getdistributekey ------------------ w_warehouse_id (1 row) 父主题: 数据库使用
  • 什么是区域、可用分区? 区域和可用分区用来描述数据中心的位置,您可以在特定的区域、可用分区创建资源。 区域(Region):从地理位置和网络时延维度划分,同一个Region内共享弹性计算、块存储、对象存储、VPC网络、弹性公网IP、镜像等公共服务。Region分为通用Region和专属Region,通用Region指面向公共租户提供通用云服务的Region;专属Region指只承载同一类业务或只面向特定租户提供业务服务的专用Region。 可用分区(AZ,Availability Zone):一个AZ是一个或多个物理数据中心的集合,有独立的风火水电,AZ内逻辑上再将计算、网络、存储等资源划分成多个集群。一个Region中的多个AZ间通过高速光纤相连,以满足用户跨AZ构建高可用性系统的需求。 图1阐明了区域和可用分区之间的关系。 图1 区域和可用分区 目前,华为云已在全球多个地域开放云服务,您可以根据需求选择适合自己的区域和可用分区。更多信息请参见华为云全球站点。
  • 如何选择区域? 选择区域时,您需要考虑以下几个因素: 地理位置 一般情况下,建议就近选择靠近您或者您的目标用户的区域,这样可以减少网络时延,提高访问速度。不过,在基础设施、BGP网络品质、资源的操作与配置等方面,中国大陆各个区域间区别不大,如果您或者您的目标用户在中国大陆,可以不用考虑不同区域造成的网络时延问题。 中国香港、曼谷等其他地区和国家提供国际带宽,主要面向非中国大陆地区的用户。如果您或者您的目标用户在中国大陆,使用这些区域会有较长的访问时延,不建议使用。 在除中国大陆以外的亚太地区有业务的用户,可以选择“亚太-曼谷”或“亚太-新加坡”区域。 在非洲地区有业务的用户,可以选择“南非-约翰内斯堡”区域。 在欧洲地区有业务的用户,可以选择“欧洲-巴黎”区域。 资源的价格 不同区域的资源价格可能有差异,请参见华为云服务价格详情。
  • 检查原因 基本原因可能有以下几种: 集群状态是否正常。 连接命令是否正确,用户名、密码、IP地址或端口无误。 安装客户端的操作系统类型、版本是否正确。 安装客户端的操作是否正确。 如果是在公有云环境无法连接,还需要检查以下可能导致异常的原因: 弹性云服务器是否与集群在相同可用分区、虚拟私有云、子网和安全组。 安全组的出入规则是否正确。 如果是在互联网环境无法连接,还需要检查以下可能导致异常的原因: 用户网络是否与互联网可以正常连通。 用户网络防火墙策略是否限制了访问。 用户网络是否需要通过代理才能访问互联网。
  • 以pg_toast_temp*或pg_temp*开头的Schema是什么? 查询Schema列表的时候,发现查询结果存在pg_temp*或pg_toast_temp*的Schema,如下图所示。 1 SELECT * FROM pg_namespace; 这些Schema是在创建临时表时,该临时表通过每个会话独立的以pg_temp开头的Schema来保证只对当前会话可见,因此,不建议用户在日常操作中手动删除以pg_temp,pg_toast_temp开头的Schema。 临时表只在当前会话可见,本会话结束后会自动删除,这些相应的Schema也会被删除。 父主题: 数据库使用
  • 同时拥有自定义路由和弹性公网IP的访问外网的优先级是什么? 弹性公网IP的优先级高于VPC路由表中的自定义路由。示例如下: 假如VPC路由表中存在一条自定义路由,目的地址为默认路由(0.0.0.0/0),下一跳为NAT网关。 如果VPC内的ECS绑定了EIP,会在ECS内增加默认网段的策略路由,并且优先级高于VPC路由表中的自定义路由,此时会导致流量转发至EIP出公网,无法抵达NAT网关。 父主题: 网络连接类
  • VPC中可以使用哪些网段(CIDR)? 您可以在特定的私有IP网段范围内,选择VPC的网段。VPC网段的选择需要考虑以下两点: IP地址数量:要为业务预留足够的IP地址,防止业务扩展给网络带来冲击。 IP地址网段:当前VPC与其他VPC、云下数据中心连通时,要避免IP地址冲突。 VPC支持的网段范围如表1所示。 表1 VPC网段 VPC网段 IP地址范围 最大IP地址数 10.0.0.0/8~24 10.0.0.0-10.255.255.255 2^24-2=16777214 172.16.0.0/12~24 172.16.0.0-172.31.255.255 2^20-2=1048574 192.168.0.0/16~24 192.168.0.0-192.168.255.255 2^16-2=65534 表1中介绍的IPv4网段是VPC的主网段,当VPC创建完成后,主网段不支持修改,若主网段不够分配,您可以为虚拟私有云添加IPv4扩展网段。 父主题: 虚拟私有云与子网类
  • 解决方案 购买ECS并进行网络配置时,请务必选择“自动分配IPv6地址”。 如果自动分配IPv6地址失败,或者您选的其他镜像不支持自动分配IPv6地址,请参考动态获取IPv6地址手动获取IPv6地址。 如果云服务器使用的是公共镜像,则支持情况如下: Linux公共镜像开启动态获取IPv6功能时,需要先判断是否支持IPv6协议栈,再判断是否已开启动态获取IPv6。目前,所有Linux公共镜像均已支持IPv6协议栈,并且Ubuntu 16操作系统已默认开启动态获取IPv6。即Ubuntu 16操作系统无需配置,其他Linux公共镜像需要执行开启动态获取IPv6的操作。 默认IPv6地址只具备私网通信能力,如果您需要通过该IPv6地址访问Internet或被Internet上的IPv6客户端访问,您需要购买和绑定共享带宽。具体请参考购买和加入共享带宽。 如您已有共享带宽,可以不用重新购买,直接将IPv6地址加入共享带宽即可。 当云服务器拥有多张网卡时,主网卡默认可以和外部正常通信,扩展网卡无法和外部正常通信,此时您需要在云服务器内部为这些网卡配置策略路由,才可以确保多张网卡均可以和外部正常通信。 如果您的云服务器是Linux云服务器,具体操作指导请参考为多网卡Linux云服务器配置策略路由 (IPv4/IPv6)。 如果您的云服务器是Windows云服务器,具体操作指导请参考为多网卡Windows云服务器配置策略路由 (IPv4/IPv6)。
  • 弹性公网IP、私有IP和虚拟IP之间有何区别? 云上不同IP地址实现的功能不同,图1展示了IP地址架构图,关于IP的详细介绍请参见表1。 图1 IP地址架构图 表1 不同IP地址功能说明 IP地址分类 IP地址说明 示例 私有IP 您在VPC子网内创建弹性云服务器时,系统会基于子网内的可用IP地址,给弹性云服务器分配私有IP地址,私有IP地址主要用于云内网络通信,不能访问Internet。 ECS-A-01的私有IP地址为172.16.0.84 ECS-B-01的私有IP地址为172.16.1.12 虚拟IP 虚拟IP是一个未分配给真实弹性云服务器网卡的IP地址,可同时绑定至多台弹性云服务器上。虚拟IP结合keepalived,可以在主弹性云服务器发生故障无法对外提供服务时,动态将虚拟IP切换到备弹性云服务器,继续对外提供服务,以此达到高可用性HA(High Availability)的目的。 虚拟IP的更多介绍请参见虚拟IP简介,高可用集群搭建方法请参见搭建Keepalived Nginx高可用Web集群。 虚拟IP(172.16.0.2)同时绑定至ECS-A-01和ECS-A-02,结合keepalived可实现ECS-A-01和ECS-A-02的主备倒换。 弹性公网IP 弹性公网IP是云上资源访问Internet使用的IP地址,可以和实例灵活绑定或者解绑。 在虚拟IP场景,您可以将弹性公网IP绑定至虚拟IP,实现虚拟IP后端的弹性云服务器访问Internet。 您可以将弹性公网IP直接绑定至弹性云服务器上,实现弹性云服务器访问Internet。 弹性公网IP的更多介绍请参见弹性公网IP简介。 将EIP(122.9.9.85)绑定至虚拟IP(172.16.0.2),实现ECS-A-01和ECS-A-02访问Internet。 将EIP(122.9.9.87)绑定至ECS-B-01,实现ECS-B-01访问Internet。 父主题: 弹性公网IP类
  • 什么是入云带宽和出云带宽? 带宽是指在单位时间(一般指的是1秒钟)内能传输的数据量,带宽数值越大表示传输能力越强,即在单位时间内传输的数据量越多。带宽分为公网带宽和内网带宽。 公网带宽是指华为云到Internet之间的网络带宽流量。公网带宽分为出云带宽和入云带宽。本文主要介绍出云带宽和入云带宽,具体内容参见表1。 图1 入云带宽和出云带宽 表1 出云带宽和入云带宽 带宽类别 描述 出云带宽 从华为云流出到Internet方向的带宽。例如,云服务器对外提供访问,或者在外网的FTP客户端下载云服务器内部的资源等方式都是使用出云带宽。 目前,华为云仅对出云带宽收取费用。 说明: 如果您需要查看带宽使用情况,请参见查看监控指标。 如果您需要查看带宽的计费详情,请参见费用账单。 入云带宽 从Internet流入华为云方向的带宽。例如,在云服务器内部下载外部网络资源,或者在外网的FTP客户端上传云服务器内部的资源等方式都是使用入云带宽。 入云带宽的最大值受用户购买的出云带宽值影响,带宽限速规则如下: 若您的带宽大小小于或等于10Mbit/s,则入云方向带宽为10Mbit/s,出云方向带宽大小为您的实际带宽大小。 若您的带宽大小大于10Mbit/s,则出云方向和入云方向带宽相同,都等于您的实际带宽大小。 上述带宽限速规则不适用华北-北京一、华东-上海二区域。 父主题: 带宽类
  • VPC的子网间是否可以通信? 不同VPC之间的网络默认不通,因此不同VPC的子网网络也不互通。 您可以使用以下方法连通不同VPC之间的网络: 通过VPC对等连接或者企业路由器ER,连通同区域的不同VPC。 对等连接,请参见对等连接简介。 企业路由器,请参见什么是企业路由器。 通过云连接CC,连通不同区域的VPC。 云连接,请参见什么是云连接。 同一个VPC内的子网网络默认互通。当您的组网中使用网络ACL和安全组防护网络安全时,也会影响子网之间的网络通信。 网络ACL:您可以根据实际情况选择是否为子网关联网络ACL,当子网关联了网络ACL,不同网络ACL的网络默认隔离。那么如果同一个VPC的子网关联不同的网络ACL,并且未添加放通规则时,网络默认不通。 安全组:VPC子网内部署的实例(如ECS)必须关联安全组,不同安全组的网络默认隔离。那么如果同一个VPC内的实例关联不同安全组,并且未添加放通规则时,网络默认不通。 当网络ACL和安全组同时存在时,流量优先匹配网络ACL规则,详细说明如表1。 图1 一个VPC内不同子网通信组网图 表1 一个VPC内不同子网通信场景说明 网络通信场景 网络安全配置 网络通信情况说明 不同子网之间通信 子网未关联网络ACL 实例关联相同安全组 子网网络默认互通:子网3和子网4未关联网络ACL,那么子网3和子网4网络互通。 子网内实例网络默认互通:ECS07、ECS08、ECS09和ECS10均关联安全组A,那么这些ECS网络互通。 子网关联相同网络ACL 实例关联不同安全组 子网网络默认互通:子网1和子网2均关联网络ACL A,那么子网1和子网2网络互通。 子网内实例网络默认不通:子网1内的ECS01和ECS02关联安全组A,子网2内的ECS05和ECS06关联安全组B,那么安全组A和安全组B未添加放通规则时,不同安全组内的ECS网络不通,比如ECS01和ECS05网络不通。 子网关联不同网络ACL 子网网络默认不通:子网1关联网络ACL A,子网5关联网络ACL B,那么网络ACL A和网络ACL B未添加放通规则时,子网1和子网5的网络不通。 此时子网网络不通,因此不论子网内ECS是否属于同一个安全组,网络均不通。 一个子网内通信 实例关联不同安全组 子网内实例网络默认不通:子网1内的ECS01和ECS02关联安全组A,ECS03和ECS04关联安全组B,那么安全组A和安全组B未添加放通规则时,即使在同一个子网内,不同安全组内的ECS网络不通,比如ECS01和ECS03网络不通。 父主题: 虚拟私有云与子网类
  • 如何通过扩展网卡绑定的弹性公网IP访问公网? 弹性公网IP绑定扩展网卡后,进入弹性云服务器,执行route命令查询路由。 route命令如果不清楚可以使用route --help。 图1 查看路由信息 执行ifconfig命令查看网卡信息。 图2 查看网卡信息 配置默认通过扩展网卡访问公网。 执行如下命令,删除主网卡默认路由。 route del -net 0.0.0.0 gw 192.168.11.1 dev eth0 参数说明:192.168.11.1是网卡所在子网的网关,可以通过管理控制台,在子网的“基本信息”页签内查看网关地址。 此操作会导致虚拟机流量中断,请谨慎操作,推荐您参考步骤4配置。 执行如下命令,配置扩展网卡默认路由。 route add default gw 192.168.17.1 按照访问的目标地址配置扩展网卡访问。 配置通过扩展网卡访问某一网段(xx.xx.0.0/16,该网段请按实际情况设置): route add -net xx.xx.0.0 netmask 255.255.0.0 gw 192.168.17.1 父主题: 弹性公网IP类
共100000条