华为云用户手册

  • 创建外部服务器 使用Data Studio连接已创建好的DWS集群。 新建一个具有创建数据库权限的用户dbuser: 1 CREATE USER dbuser WITH CREATEDB PASSWORD 'password'; 切换为新建的dbuser用户: 1 SET ROLE dbuser PASSWORD 'password'; 创建新的mydatabase数据库: 1 CREATE DATABASE mydatabase; 执行以下步骤切换为连接新建的mydatabase数据库。 在Data Studio客户端的“对象浏览器”窗口,右键单击数据库连接名称,在弹出菜单中单击“刷新”,刷新后就可以看到新建的数据库。 右键单击“mydatabase”数据库名称,在弹出菜单中单击“打开连接”。 右键单击“mydatabase”数据库名称,在弹出菜单中单击“打开新的终端”,即可打开连接到指定数据库的SQL命令窗口,后面的步骤,请全部在该命令窗口中执行。 为dbuser用户授予创建外部服务器的权限,8.1.1及以后版本,还需要授予使用public模式的权限: 1 2 GRANT ALL ON FOREIGN DATA WRAPPER hdfs_fdw TO dbuser; GRANT ALL ON SCHEMA public TO dbuser; //8.1.1及以后版本,普通用户对public模式无权限,需要赋权,8.1.1之前版本不需要执行。 其中FOREIGN DATA WRAPPER的名字只能是hdfs_fdw,dbuser为创建SERVER的用户名。 执行以下命令赋予用户使用外表的权限。 1 ALTER USER dbuser USEFT; 切换回Postgres系统数据库,查询创建 MRS 数据源后系统自动创建的外部服务器。 1 SELECT * FROM pg_foreign_server; 返回结果如: 1 2 3 4 5 6 srvname | srvowner | srvfdw | srvtype | srvversion | srvacl | srvoptions --------------------------------------------------+----------+--------+---------+------------+--------+--------------------------------------------------------------------------------------------------------------------- gsmpp_server | 10 | 13673 | | | | gsmpp_errorinfo_server | 10 | 13678 | | | | hdfs_server_8f79ada0_d998_4026_9020_80d6de2692ca | 16476 | 13685 | | | | {"address=192.168.1.245:9820,192.168.1.218:9820",hdfscfgpath=/MRS/8f79ada0-d998-4026-9020-80d6de2692ca,type=hdfs} (3 rows) 切换到mydatabase数据库,并切换到dbuser用户。 1 SET ROLE dbuser PASSWORD 'password'; 创建外部服务器。 SERVER名字、地址、配置路径保持与8一致即可。 1 2 3 4 5 6 7 CREATE SERVER hdfs_server_8f79ada0_d998_4026_9020_80d6de2692ca FOREIGN DATA WRAPPER HDFS_FDW OPTIONS ( address '192.168.1.245:9820,192.168.1.218:9820', //MRS管理面的Master主备节点的内网IP,可与DWS通讯。 hdfscfgpath '/MRS/8f79ada0-d998-4026-9020-80d6de2692ca', type 'hdfs' ); 查看外部服务器。 1 SELECT * FROM pg_foreign_server WHERE srvname='hdfs_server_8f79ada0_d998_4026_9020_80d6de2692ca'; 返回结果如下所示,表示已经创建成功: 1 2 3 4 srvname | srvowner | srvfdw | srvtype | srvversion | srvacl | srvoptions --------------------------------------------------+----------+--------+---------+------------+--------+--------------------------------------------------------------------------------------------------------------------- hdfs_server_8f79ada0_d998_4026_9020_80d6de2692ca | 16476 | 13685 | | | | {"address=192.168.1.245:9820,192.168.1.218:9820",hdfscfgpath=/MRS/8f79ada0-d998-4026-9020-80d6de2692ca,type=hdfs} (1 row)
  • 零售业百货公司样例简介 本实践将演示以下场景:从OBS加载各个零售商场每日经营的业务数据到 数据仓库 对应的表中,然后对商铺营业额、客流信息、月度销售排行、月度客流转化率、月度租售比、销售坪效等KPI信息进行汇总和查询。本示例旨在展示在零售业场景中 GaussDB (DWS) 数据仓库的多维度查询分析的能力。 GaussDB(DWS) 已预先将样例数据上传到OBS桶的“retail-data”文件夹中,并给所有华为云用户赋予了该OBS桶的只读访问权限。
  • 支持区域 当前已上传OBS数据的区域如表1所示。 表1 区域和OBS桶名 区域 OBS桶名 华北-北京一 dws-demo-cn-north-1 华北-北京二 dws-demo-cn-north-2 华北-北京四 dws-demo-cn-north-4 华北-乌兰察布一 dws-demo-cn-north-9 华东-上海一 dws-demo-cn-east-3 华东-上海二 dws-demo-cn-east-2 华南-广州 dws-demo-cn-south-1 华南-广州友好 dws-demo-cn-south-4 中国-香港 dws-demo-ap-southeast-1 亚太-新加坡 dws-demo-ap-southeast-3 亚太-曼谷 dws-demo-ap-southeast-2 拉美-圣地亚哥 dws-demo-la-south-2 非洲-约翰内斯堡 dws-demo-af-south-1 拉美-墨西哥城一 dws-demo-na-mexico-1 拉美-墨西哥城二 dws-demo-la-north-2 莫斯科二 dws-demo-ru-northwest-2 拉美-圣保罗一 dws-demo-sa-brazil-1
  • 迁移流程 本教程演示将Oracle业务相关的表数据迁移到GaussDB(DWS)的数据库的基本过程,迁移流程如图2和表1所示。 图1 迁移场景图 本实践以迁移Oracle中所属用户名db_user01下的表APEX2_DYNAMIC_ADD_REMAIN_TEST数据为例。 网络互通说明:本实践的Oracle数据库在云下,通过 云数据迁移 服务 CDM 连接Oracle和DWS。其中CDM通过公网IP与Oracle连通;CDM与DWS默认在同一个区域、虚拟私有云下,网络互通。实际迁移过程请确保网络互通,本章节不详细介绍网络如何打通。 本实践仅作为参考演示,实际迁移的复杂度可能受客户现网的网络环境、业务复杂度、节点规模、数据量等因素影响,项目实际迁移时建议在技术支持人员的指导下完成。 图2 Oracle迁移到DWS基本流程 表1 Oracle迁移到DWS基本流程 流程 描述 准备工具 迁移前需准备的软件工具。 迁移表定义 使用PL/SQL Developer工具进行表定义迁移。 迁移表全量数据 使用华为云迁移服务CDM完成进行数据迁移。 迁移业务SQL 使用DSC语法迁移工具进行语法改写,使Oracle的业务SQL转换成适配DWS的SQL。 父主题: 使用CDM迁移Oracle数据至GaussDB(DWS)集群
  • 技术背景 哈希函数 哈希函数又称为摘要算法,对于数据data,Hash函数会生成固定长度的数据,即Hash(data)=result。这个过程是不可逆的,即Hash函数不存在反函数,无法由result得到data。在不应保存明文场景(比如口令password属于敏感信息),系统管理员用户也不应该知道用户的明文口令,就应该使用哈希算法存储口令的单向哈希值。 实际使用中会加入盐值和迭代次数,避免相同口令生成相同的哈希值,以防止彩虹表攻击。 对称密码算法 对称密码算法使用相同的密钥来加密和解密数据。对称密码算法分为分组密码算法和流密码算法。 分组密码算法将明文分成固定长度的分组,用密钥对每个分组加密。由于分组长度固定,当明文长度不是分组长度的整数倍时,会对明文做填充处理。由于填充的存在,分组密码算法得到的密文长度会大于明文长度。 流加密算法是指加密和解密双方使用相同伪随机加密数据流作为密钥,明文数据依次与密钥数据流顺次对应加密,得到密文数据流。实践中数据通常是一个位(bit)并用异或(xor)操作加密。流密码算法不需要填充,得到的密文长度等于明文长度。 图1 对称密码算法
  • 技术实现 GaussDB(DWS)主要提供了哈希函数和对称密码算法来实现对数据列的加解密。哈希函数支持sha256,sha384,sha512和国密sm3。对称密码算法支持aes128,aes192,aes256和国密sm4。 哈希函数 md5(string) 将string使用MD5加密,并以16进制数作为返回值。MD5的安全性较低,不建议使用。 gs_hash(hashstr, hashmethod) 以hashmethod算法对hashstr字符串进行信息摘要,返回信息摘要字符串。支持的hashmethod:sha256,sha384,sha512,sm3。 对称密码算法 gs_encrypt(encryptstr, keystr, cryptotype, cryptomode, hashmethod) 采用cryptotype和cryptomode组成的加密算法以及hashmethod指定的HMAC算法,以keystr为密钥对encryptstr字符串进行加密,返回加密后的字符串。 gs_decrypt(decryptstr, keystr, cryptotype, cryptomode, hashmethod) 采用cryptotype和cryptomode组成的加密算法以及hashmethod指定的HMAC算法,以keystr为密钥对decryptstr字符串进行解密,返回解密后的字符串。解密使用的keystr必须保证与加密时使用的keystr一致才能正常解密。 gs_encrypt_aes128(encryptstr, keystr) 以keystr为密钥对encryptstr字符串进行加密,返回加密后的字符串。keystr的长度范围为1~16字节。 gs_decrypt_aes128(decryptstr, keystr) 以keystr为密钥对decryptstr字符串进行解密,返回解密后的字符串。解密使用的keystr必须保证与加密时使用的keystr一致才能正常解密。keystr不得为空。 有关函数的更多内容,请参见使用函数加解密。
  • 应用示例 连接数据库。 具体步骤参见使用命令行工具连接GaussDB(DWS)集群。 创建表student,有id、name和score三个字段。使用哈希函数加密保存name,使用对称密码算法保存score。 1 2 3 4 5 CREATE TABLE student (id int, name text, score text, subject text); INSERT INTO student VALUES (1, gs_hash('alice', 'sha256'), gs_encrypt('95', '12345', 'aes128', 'cbc', 'sha256'),gs_encrypt_aes128('math', '1234')); INSERT INTO student VALUES (2, gs_hash('bob', 'sha256'), gs_encrypt('92', '12345', 'aes128', 'cbc', 'sha256'),gs_encrypt_aes128('english', '1234')); INSERT INTO student VALUES (3, gs_hash('peter', 'sha256'), gs_encrypt('98', '12345', 'aes128', 'cbc', 'sha256'),gs_encrypt_aes128('science', '1234')); 不使用密钥查询表student,通过查询结果可知:没有密钥的用户即使拥有了SELECT权限也无法看到name和score这两列加密数据。 1 2 3 4 5 6 7 8 9 10 11 12 SELECT * FROM student; id | name | score | subject ----+------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------+----------- ----------------------------------------------------------------------------------- 1 | 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 | AAAAAAAAAABAuUC3VQ+MvPCDAaTUySl1e2gGLr4/ATdCUjTEvova3cb/Ba3ZKqIn1yNVGEFBvJnTq/3sLF4//Gm8qG7AyfNbbqdW3aYErLVpbE/QWFX9Ig== | aFEWQR2gkj iu6sfsAad+dHzfFDHePZ6xd44zyekh+qVFlh9FODZ0DoaFAJXctwUsiqaiitTxW8c CS EaNjS/E7Ke1ruY= 2 | 81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9 | AAAAAAAAAABAuUC3VQ+MvPCDAaTUySl1taXxAoDqE793hgyCJvC0ESdAX5Mtgdq2LXI1f5ZxraQ73WIJVtIBX8oe3gTDxoXGlHbHht4kzM4U8dOwr5rjgg== | aFEWQR2gkj iu6sfsAad+dM8tPTDo/Pds6ZmqdmjGiKxf39+Wzx5NoQ6c8FrzihnRzgc0fycWSu5YGWNOKYWhRsE84Ac= 3 | 026ad9b14a7453b7488daa0c6acbc258b1506f52c441c7c465474c1a564394ff | AAAAAAAAAACnyusORPeApqMUgh56ucQu3uso/Llw5MbPFMkOXuspEzhhnc9vErwOFe6cuGtx8muEyHCX7V5yXs+8FxhNh3n5L3419LDWJJLY2O4merHpSg== | zomphRfHV4 H32hTtgkio1PyrobVO8N+hN7kAKwtygKP2E7Aaf1vsjmtLHcL88jyeJNe1lxe0fAvodzPJAxAuV3UJN4M= (3 rows) 使用密钥查询表student,通过查询结果可知:拥有密钥的用户通过使用gs_encrypt对应的解密函数gs_decrypt解密后,可以查看加密数据。 1 2 3 4 5 6 7 SELECT id, gs_decrypt(score, '12345', 'aes128', 'cbc', 'sha256'),gs_decrypt_aes128(subject, '1234') FROM student; id | gs_decrypt | gs_decrypt_aes128 ----+------------+------------------- 1 | 95 | math 2 | 92 | english 3 | 98 | science (3 rows)
  • 约束限制 在使用分区管理功能时,需要满足如下约束: 不支持在小型机、加速集群、单机集群上使用。 支持在8.1.3及以上集群版本中使用。 仅支持行存范围分区表、列存范围分区表、时序表以及冷热表。 分区键唯一且类型仅支持timestamp、timestamptz、date类型。 不支持存在maxvalue分区。 (nowTime - boundaryTime) / period需要小于分区个数上限,其中nowTime为当前时间,boundaryTime为现有分区中最早的分区边界时间。 period、ttl取值范围为1hour ~ 100years。另外,在兼容Teradata或MySQL的数据库中,分区键类型为date时,period不能小于1day。 表级参数ttl不支持单独存在,必须要提前或同时设置period,并且要大于或等于period。 集群在线扩容期间,自动增加分区会失败,但是由于每次增分区时,都预留了足够的分区,所以不影响使用。
  • 分区自动管理 分区管理功能是和表级参数period、ttl绑定的,只要成功设置了表级参数period,即开启了自动创建新分区功能;成功设置了表级参数ttl,即开启了自动删除过期分区功能。第一次自动创建分区或删除分区的时间为设置period或ttl后30秒。 有如下两种开启分区管理功能的方式: 建表时指定period、ttl。 该方式适用于新建分区管理表时使用。新建分区管理表有两种语法:一种是建表时指定分区,另一种是建表时不指定分区。 建分区管理表时如果指定分区,则语法规则和建普通分区表相同,唯一的区别就是会指定表级参数period、ttl。 示例:创建分区管理表CPU1,指定分区。 1 2 3 4 5 6 7 8 9 10 CREATE TABLE CPU1( id integer, IP text, time timestamp ) with (TTL='7 days',PERIOD='1 day') partition by range(time) ( PARTITION P1 VALUES LESS THAN('2023-02-13 16:32:45'), PARTITION P2 VALUES LESS THAN('2023-02-15 16:48:12') ); 建分区管理表时可以只指定分区键不指定分区,此时将创建两个默认分区,这两个默认分区的分区时间范围均为period。其中,第一个默认分区的边界时间是大于当前时间的第一个整时/整天/整周/整月/整年的时间,具体选择哪种整点时间取决于period的最大单位;第二个默认分区的边界时间是第一个分区边界时间加period。假设当前时间是2023-02-17 16:32:45,各种情况的第一个默认分区的分区边界选择如下表: 表2 period参数说明 period period最大单位 第一个默认分区的分区边界 1hour Hour 2023-02-17 17:00:00 1day Day 2023-02-18 00:00:00 1month Month 2023-03-01 00:00:00 13months Year 2024-01-01 00:00:00 创建分区管理表CPU2,不指定分区: 1 2 3 4 5 6 CREATE TABLE CPU2( id integer, IP text, time timestamp ) with (TTL='7 days',PERIOD='1 day') partition by range(time); 使用ALTER TABLE RESET的方式设置period、ttl。 该方式适用于给一张满足分区管理约束的普通分区表增加分区管理功能。 创建普通分区表CPU3: 1 2 3 4 5 6 7 8 9 10 CREATE TABLE CPU3( id integer, IP text, time timestamp ) partition by range(time) ( PARTITION P1 VALUES LESS THAN('2023-02-14 16:32:45'), PARTITION P2 VALUES LESS THAN('2023-02-15 16:56:12') ); 同时开启自动创建和自动删除分区功能: 1 ALTER TABLE CPU3 SET (PERIOD='1 day',TTL='7 days'); 只开启自动创建分区功能: 1 ALTER TABLE CPU3 SET (PERIOD='1 day'); 只开启自动删除分区功能,如果没有提前开启自动创建分区功能,则开启失败: 1 ALTER TABLE CPU3 SET (TTL='7 days'); 通过修改period和ttl修改分区管理功能: 1 ALTER TABLE CPU3 SET (TTL='10 days',PERIOD='2 days'); 关闭分区管理功能。 使用ALTER TABLE RESET语句可以删除表级参数period、ttl,即可关闭相应的分区管理功能。 不能在存在ttl的情况下,单独删除period。 时序表不支持ALTER TABLE RESET。 同时关闭自动创建和自动删除分区功能: 1 ALTER TABLE CPU1 RESET (PERIOD,TTL); 只关闭自动删除分区功能: 1 ALTER TABLE CPU3 RESET (TTL); 只关闭自动创建分区功能,如果该表有ttl参数,则关闭失败: 1 ALTER TABLE CPU3 RESET (PERIOD);
  • 查看连接信息 设置参数track_activities为on: SET track_activities = on; 当此参数为on时,数据库系统才会收集当前活动查询的运行信息。 通过以下SQL就能确认当前的连接用户、连接地址、连接应用、状态、是否等待锁、排队状态以及线程id。 1 SELECT usename,client_addr,application_name,state,waiting,enqueue,pid FROM PG_STAT_ACTIVITY WHERE DATNAME='数据库名称'; 回显如下: 1 2 3 4 5 6 usename | client_addr | application_name | state | waiting | enqueue | pid ---------+---------------+------------------+--------+---------+---------+----------------- leo | 192.168.0.133 | gsql | idle | f | | 139666091022080 dbadmin | 192.168.0.133 | gsql | active | f | | 139666212681472 joe | 192.168.0.133 | | idle | f | | 139665671489280 (3 rows) 中止某个会话连接(仅系统管理员有权限): 1 SELECT PG_TERMINATE_BACKEND(pid);
  • 查看SQL运行信息 获取当前用户有权限查看的所有的SQL信息(若有管理员权限或预置角色权限可以显示和所有用户查询相关的信息): 1 SELECT usename,state,query FROM PG_STAT_ACTIVITY WHERE DATNAME='数据库名称'; 如果state为active,则query列表示当前执行的SQL语句,其他情况则表示为上一个查询语句;如果state字段显示为idle,则表明此连接处于空闲,等待用户输入命令。回显如下: 1 2 3 4 5 6 usename | state | query ---------+--------+--------------------------------------------------------------------------- leo | idle | select * from joe.mytable; dbadmin | active | SELECT usename,state,query FROM PG_STAT_ACTIVITY WHERE DATNAME='gaussdb'; joe | idle | GRANT SELECT ON TABLE mytable to leo; (3 rows)
  • 场景 dbadmin用户连接集群后,创建示例表customer: 1 CREATE TABLE customer (id bigserial NOT NULL, province_id bigint NOT NULL, user_info varchar, primary key (id)) DISTRIBUTE BY HASH(id); 向示例表customer插入测试数据: 1 2 INSERT INTO customer(province_id,user_info) VALUES (1,'Alice'),(1,'Jack'),(2,'Jack'),(3,'Matu'); INSERT 0 4 查询示例表customer: 1 2 3 4 5 6 7 8 SELECT * FROM customer; id | province_id | user_info ----+-------------+----------- 3 | 2 | Jack 1 | 1 | Alice 2 | 1 | Jack 4 | 3 | Matu (4 rows)
  • 查询结果验证 切换到u1账号连接集群。 1 SET ROLE u1 PASSWORD '*********'; 查询v1视图,u1仅能查询到视图v1数据。 1 2 3 4 5 6 SELECT * FROM dbadmin.v1; id | province_id | user_info ----+-------------+----------- 1 | 1 | Alice 2 | 1 | Jack (2 rows) 若u1试图查询视图v2中的数据,则会返回如下报错: 1 2 SELECT * FROM dbadmin.v2; ERROR: SELECT permission denied to user "u1" for relation "dbadmin.v2" 结果显示用户u1仅能查看省份1(即province_id=1)的数据。 使用u2账号连接集群。 1 SET ROLE u2 PASSWORD '*********'; 查询v2视图,u2仅能查询到视图v2数据。 1 2 3 4 5 SELECT * FROM dbadmin.v2; id | province_id | user_info ----+-------------+----------- 3 | 2 | Jack (1 row) 若u2试图查询视图v1中的数据,则会返回如下报错: 1 2 SELECT * FROM dbadmin.v1; ERROR: SELECT permission denied to user "u2" for relation "dbadmin.v1" 结果显示用户u2仅能查看省份2(即province_id=2)的数据。
  • 实现方式 通过创建视图实现上述场景中的需求,具体操作步骤如下: dbadmin用户连接集群后,在dbadmin模式下为省份1和省份2分别创建视图v1和视图v2。 使用CREATE VIEW语句创建查询省份1数据的视图v1: 1 2 CREATE VIEW v1 AS SELECT * FROM customer WHERE province_id=1; 使用CREATE VIEW语句创建查询省份2数据的视图v2: 1 2 CREATE VIEW v2 AS SELECT * FROM customer WHERE province_id=2; 创建用户u1和u2。 1 2 CREATE USER u1 PASSWORD '*********'; CREATE USER u2 PASSWORD '*********'; 使用GRANT语句将对应的数据查询权限授予目标用户。 授予u1和u2对应视图schema的权限。 1 GRANT USAGE ON schema dbadmin TO u1,u2; 授予u1通过v1视图查询省份1数据的权限: 1 GRANT SELECT ON v1 TO u1; 授予u2通过v2视图查询省份2数据的权限: 1 GRANT SELECT ON v2 TO u2;
  • 步骤四:车辆分析 执行ANALYZE。 用于收集与数据库中普通表内容相关的统计信息,统计结果存储在系统表PG_STATISTIC中。执行计划生成器会使用这些统计数据,以生成最有效的查询执行计划。 执行以下语句生成表统计信息: 1 ANALYZE; 查询数据表中的数据量。 执行如下语句,可以查看已加载的数据条数。 1 2 SET current_schema= traffic_data; SELECT count(*) FROM traffic_data.gcjl; 车辆精确查询。 执行以下语句,指定车牌号码和时间段查询车辆行驶路线。GaussDB(DWS)在应对点查时秒级响应。 1 2 3 4 5 6 SET current_schema= traffic_data; SELECT hphm, kkbh, gcsj FROM traffic_data.gcjl where hphm = 'YD38641' and gcsj between '2016-01-06' and '2016-01-07' order by gcsj desc; 车辆模糊查询。 执行以下语句,指定车牌号码和时间段查询车辆行驶路线,GaussDB(DWS) 在应对模糊查询时秒级响应。 1 2 3 4 5 6 7 SET current_schema= traffic_data; SELECT hphm, kkbh, gcsj FROM traffic_data.gcjl where hphm like 'YA23F%' and kkbh in('508', '1125', '2120') and gcsj between '2016-01-01' and '2016-01-07' order by hphm,gcsj desc;
  • 支持区域 当前已上传OBS数据的区域如表1所示。 表1 区域和OBS桶名 区域 OBS桶名 华北-北京一 dws-demo-cn-north-1 华北-北京二 dws-demo-cn-north-2 华北-北京四 dws-demo-cn-north-4 华北-乌兰察布一 dws-demo-cn-north-9 华东-上海一 dws-demo-cn-east-3 华东-上海二 dws-demo-cn-east-2 华南-广州 dws-demo-cn-south-1 华南-广州友好 dws-demo-cn-south-4 中国-香港 dws-demo-ap-southeast-1 亚太-新加坡 dws-demo-ap-southeast-3 亚太-曼谷 dws-demo-ap-southeast-2 拉美-圣地亚哥 dws-demo-la-south-2 非洲-约翰内斯堡 dws-demo-af-south-1 拉美-墨西哥城一 dws-demo-na-mexico-1 拉美-墨西哥城二 dws-demo-la-north-2 莫斯科二 dws-demo-ru-northwest-2 拉美-圣保罗一 dws-demo-sa-brazil-1
  • 导入数据 使用如下语句在GaussDB(DWS)中创建目标表product_info,用于存储导入的数据。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 DROP TABLE IF EXISTS product_info; CREATE TABLE product_info ( product_price integer not null, product_id char(30) not null, product_time date , product_level char(10) , product_name varchar(200) , product_type1 varchar(20) , product_type2 char(10) , product_monthly_sales_cnt integer , product_comment_time date , product_comment_num integer , product_comment_content varchar(200) ) WITH ( orientation = column, compression=middle ) DISTRIBUTE BY hash (product_id); 将数据源文件中的数据通过外表“product_info_ext”导入到表“product_info”中。 1 INSERT INTO product_info SELECT * FROM product_info_ext ; 返回如下信息,表示数据导入成功。 1 INSERT 0 20 执行SELECT命令查询目标表product_info,查看导入到GaussDB(DWS)中的数据。 1 SELECT count(*) FROM product_info; 查询结果显示结果如下,表示导入成功。 1 2 3 4 count ------- 20 (1 row) 对表product_info执行VACUUM FULL。 1 VACUUM FULL product_info 更新表product_info的统计信息。 1 ANALYZE product_info;
  • 停止GDS 以gds_user用户登录安装GDS的数据服务器。 使用以下方式停止GDS。 执行如下命令,查询GDS进程号。其中,GDS进程号为128954。 ps -ef|grep gds gds_user 128954 1 0 15:03 ? 00:00:00 gds -d /input_data/ -p 192.168.0.90:5000 -l /opt/bin/gds/gds_log.txt -D gds_user 129003 118723 0 15:04 pts/0 00:00:00 grep gds 使用“kill”命令,停止GDS。其中,128954为上一步骤中查询出的GDS进程号。 kill -9 128954
  • 清除资源 执行以下命令,删除目标表product_info。 1 DROP TABLE product_info; 当结果显示为如下信息,表示删除成功。 1 DROP TABLE 执行以下命令,删除外表product_info_ext。 1 DROP FOREIGN TABLE product_info_ext; 当结果显示为如下信息,表示删除成功。 1 DROP FOREIGN TABLE
  • 安装并启动GDS 以root用户登录GDS服务器,创建存放GDS工具包的目录/opt/bin/dws。 1 mkdir -p /opt/bin/dws 将GDS工具包上传至上一步所创建的目录中。 以上传redhat版本的工具包为例 ,将GDS工具包“dws_client_8.1.x_redhat_x64.zip”上传至上一步所创建的目录中。 在工具包所在目录下,解压工具包。 1 2 cd /opt/bin/dws unzip dws_client_8.1.x_redhat_x64.zip 创建用户gds_user及其所属的用户组gdsgrp。此用户用于启动GDS,且需要拥有读取数据源文件目录的权限。 1 2 groupadd gdsgrp useradd -g gdsgrp gds_user 修改工具包以及数据源文件目录属主为创建的用户gds_user及其所属的用户组gdsgrp。 1 2 chown -R gds_user:gdsgrp /opt/bin/dws/gds chown -R gds_user:gdsgrp /input_data 切换到gds_user用户。 1 su - gds_user 若当前集群版本为8.0.x及之前低版本,请跳过7,直接执行8。 若当前集群版本为8.1.x及以上版本,则正常执行以下步骤。 执行环境依赖脚本。(仅8.1.x版本适用) 1 2 cd /opt/bin/dws/gds/bin source gds_env 启动GDS。 1 /opt/bin/dws/gds/bin/gds -d /input_data/ -p 192.168.0.90:5000 -H 10.10.0.1/24 -l /opt/bin/dws/gds/gds_log.txt -D 命令中的部分信息请根据实际填写。 -d dir:保存有待导入数据的数据文件所在目录。本教程中为“/input_data/”。 -p ip:port:GDS监听IP和监听端口。默认值为:127.0.0.1,需要替换为能跟GaussDB(DWS)通信的万兆网IP。监听端口的取值范围:1024~65535。默认值为:8098。本教程配置为:192.168.0.90:5000。 -H address_string:允许哪些主机连接和使用GDS服务。参数需为CIDR格式。此参数配置的目的是允许GaussDB(DWS)集群可以访问GDS服务进行数据导入。所以请保证所配置的网段包含GaussDB(DWS)集群各主机。 -l log_file:存放GDS的日志文件路径及文件名。本教程为“/opt/bin/dws/gds/gds_log.txt”。 -D:后台运行GDS。仅支持Linux操作系统下使用。
  • 创建外表 使用SQL客户端工具连接GaussDB(DWS)数据库。 创建如下外表: LOCATION:请替换成实际的GDS地址和端口。 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 DROP FOREIGN TABLE IF EXISTS product_info_ext; CREATE FOREIGN TABLE product_info_ext ( product_price integer not null, product_id char(30) not null, product_time date , product_level char(10) , product_name varchar(200) , product_type1 varchar(20) , product_type2 char(10) , product_monthly_sales_cnt integer , product_comment_time date , product_comment_num integer , product_comment_content varchar(200) ) SERVER gsmpp_server OPTIONS( LOCATION 'gsfs://192.168.0.90:5000/*', FORMAT 'CSV' , DELIMITER ',', ENCODING 'utf8', HEADER 'false', FILL_MISSING_FIELDS 'true', IGNORE_EXTRA_DATA 'true' ) READ ONLY LOG INTO product_info_err PER NODE REJECT LIMIT 'unlimited'; 返回如下信息表示创建成功: 1 CREATE FOREIGN TABLE
  • 教程指引 本教程旨在演示使用GDS(General Data Service)工具将远端服务器上的数据导入GaussDB(DWS)中的过程,帮助您学习如何通过GDS进行数据导入的方法。 GaussDB(DWS)支持通过GDS外表将TXT、CSV和FIXED格式的数据导入到集群进行查询。 在本教程中,您将: 生成本教程需要使用的CSV格式的数据源文件。 将数据源文件上传到数据服务器。 创建外表,用于对接GDS和GaussDB(DWS),将数据服务器上的数据导入到GaussDB(DWS)集群中。 启动GaussDB(DWS)并创建数据库表后,将数据导入到表中。 根据错误表中的提示诊断加载错误并更正这些错误。
  • 通过外表导入远端DWS数据 参见7在ECS上连接第二套集群,其中连接地址改为第二套集群的地址,本例为192.168.0.86。 创建普通用户jim,并赋予创建外表和server的权限。FOREIGN DATA WRAPPER固定为gc_fdw。 1 2 3 CREATE USER jim WITH PASSWORD 'password'; ALTER USER jim USEFT; GRANT ALL ON FOREIGN DATA WRAPPER gc_fdw TO jim; 切换到jim用户,创建server。 1 2 3 4 5 6 7 SET ROLE jim PASSWORD 'password'; CREATE SERVER server_remote FOREIGN DATA WRAPPER gc_fdw OPTIONS (address '192.168.0.8:8000,192.168.0.158:8000' , dbname 'gaussdb', username 'leo', password 'password' ); address:第一套集群的两个内网IP和端口,参见6获取,本例为192.168.0.8:8000,192.168.0.158:8000。 dbname:连接的第一套集群的数据库名,本例为gaussdb。 username:连接的第一套集群的用户名,本例为leo。 password:用户名密码。 创建外表。 外表的字段和约束,必须与待访问表的字段和约束保持一致。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 CREATE FOREIGN TABLE region ( product_price integer , product_id char(30) , product_time date , product_level char(10) , product_name varchar(200) , product_type1 varchar(20) , product_type2 char(10) , product_monthly_sales_cnt integer , product_comment_time date , product_comment_num integer , product_comment_content varchar(200) ) SERVER server_remote OPTIONS ( schema_name 'leo', table_name 'product_info', encoding 'utf8' ); SERVER:上一步创建的server的名称,本例为server_remote。 schema_name:待访问的第一套集群的schema名称,本例为leo。 table_name:待访问的第一套集群的表名,参见10获取,本例为product_info。 encoding:保持与第一套集群的数据库编码一致,参见9获取,本例为utf8。 查看创建的server和外表。 1 2 \des+ server_remote \d+ region 创建本地表。 表的字段和约束,必须与待访问表的字段和约束保持一致。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CREATE TABLE local_region ( product_price integer not null, product_id char(30) not null, product_time date , product_level char(10) , product_name varchar(200) , product_type1 varchar(20) , product_type2 char(10) , product_monthly_sales_cnt integer , product_comment_time date , product_comment_num integer , product_comment_content varchar(200) ) WITH ( orientation = column, compression=middle ) DISTRIBUTE BY hash (product_id); 通过外表导入数据到本地表。 1 2 INSERT INTO local_region SELECT * FROM region; SELECT * FROM local_region; 您也可以直接查询外表而无需将数据导入。 1 SELECT * FROM region;
  • 使用GDS导入数据源 使用root账户登录ECS,使用文件传输工具将7下载好的工具包上传到/opt目录下。 在/opt目录下解压工具包。 cd /opt unzip dws_client_8.1.x_redhat_x64.zip 创建GDS用户,并修改数据源目录和GDS目录的属主。 groupadd gdsgrp useradd -g gdsgrp gds_user chown -R gds_user:gdsgrp /opt/gds chown -R gds_user:gdsgrp /input_data 切换到gds_user用户。 su - gds_user 导入GDS环境变量。 仅8.1.x及以上版本需要执行,低版本请跳过。 cd /opt/gds/bin source gds_env 启动GDS。 /opt/gds/bin/gds -d /input_data/ -p 192.168.0.90:5000 -H 192.168.0.0/24 -l /opt/gds/gds_log.txt -D -d dir:保存有待导入数据的数据文件所在目录。本教程中为“/input_data/”。 -p ip:port:GDS监听IP和监听端口。配置为GDS所在的ECS的内网IP,可与DWS通讯,本例为192.168.0.90:5000。 -H address_string:允许哪些主机连接和使用GDS服务。参数需为CIDR格式。本例设置为DWS的内网IP所在的网段即可。 -l log_file:存放GDS的日志文件路径及文件名。本教程为“/opt/gds/gds_log.txt”。 -D:后台运行GDS。 使用gsql连接第一套DWS集群。 执行exit切换root用户,进入ECS的/opt目录,导入gsql的环境变量。 exit cd /opt source gsql_env.sh 进入/opt/bin目录,使用gsql连接第一套DWS集群。 cd /opt/bin gsql -d gaussdb -h 192.168.0.8 -p 8000 -U dbadmin -W password -r -d: 连接的数据库名,本例为默认数据库gaussdb。 -h:连接的DWS内网IP,即6查询到的内网IP,本例为192.168.0.8。 -p:DWS端口,固定为8000。 -U:数据库管理员用户,默认为dbadmin。 -W:管理员用户的密码,为3创建集群时设置的密码,本例password为用户创建集群设置的密码。 创建普通用户leo,并赋予创建外表的权限。 1 2 CREATE USER leo WITH PASSWORD 'password'; ALTER USER leo USEFT; 切换到leo用户,创建GDS外表。 以下LOCATION参数请填写为6的GDS的监听IP和端口,后面加上/*,例如:gsfs://192.168.0.90:5000/* 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 SET ROLE leo PASSWORD 'password'; DROP FOREIGN TABLE IF EXISTS product_info_ext; CREATE FOREIGN TABLE product_info_ext ( product_price integer not null, product_id char(30) not null, product_time date , product_level char(10) , product_name varchar(200) , product_type1 varchar(20) , product_type2 char(10) , product_monthly_sales_cnt integer , product_comment_time date , product_comment_num integer , product_comment_content varchar(200) ) SERVER gsmpp_server OPTIONS( LOCATION 'gsfs://192.168.0.90:5000/*', FORMAT 'CSV' , DELIMITER ',', ENCODING 'utf8', HEADER 'false', FILL_MISSING_FIELDS 'true', IGNORE_EXTRA_DATA 'true' ) READ ONLY LOG INTO product_info_err PER NODE REJECT LIMIT 'unlimited'; 创建本地表。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 DROP TABLE IF EXISTS product_info; CREATE TABLE product_info ( product_price integer not null, product_id char(30) not null, product_time date , product_level char(10) , product_name varchar(200) , product_type1 varchar(20) , product_type2 char(10) , product_monthly_sales_cnt integer , product_comment_time date , product_comment_num integer , product_comment_content varchar(200) ) WITH ( orientation = column, compression=middle ) DISTRIBUTE BY hash (product_id); 从GDS外表导入数据并查询,数据导入成功。 1 2 INSERT INTO product_info SELECT * FROM product_info_ext ; SELECT count(*) FROM product_info;
  • 准备源数据 在本地PC指定目录下,创建以下3个.csv格式的文件,数据样例如下。 数据文件“product_info0.csv” 1 2 3 4 5 100,XHDK-A,2017-09-01,A,2017 Shirt Women,red,M,328,2017-09-04,715,good! 205,KDKE-B,2017-09-01,A,2017 T-shirt Women,pink,L,584,2017-09-05,40,very good! 300,JODL-X,2017-09-01,A,2017 T-shirt men,red,XL,15,2017-09-03,502,Bad. 310,QQPX-R,2017-09-02,B,2017 jacket women,red,L,411,2017-09-05,436,It's nice. 150,ABEF-C,2017-09-03,B,2017 Jeans Women,blue,M,123,2017-09-06,120,good. 数据文件“product_info1.csv” 1 2 3 4 5 200,BCQP-E,2017-09-04,B,2017 casual pants men,black,L,997,2017-09-10,301,good quality. 250,EABE-D,2017-09-10,A,2017 dress women,black,S,841,2017-09-15,299,This dress fits well. 108,CDXK-F,2017-09-11,A,2017 dress women,red,M,85,2017-09-14,22,It's really amazing to buy. 450,MMCE-H,2017-09-11,A,2017 jacket women,white,M,114,2017-09-14,22,very good. 260,OCDA-G,2017-09-12,B,2017 woolen coat women,red,L,2004,2017-09-15,826,Very comfortable. 数据文件“product_info2.csv” 1 2 3 4 5 6 7 8 9 10 980,"ZKDS-J",2017-09-13,"B","2017 Women's Cotton Clothing","red","M",112,,, 98,"FKQB-I",2017-09-15,"B","2017 new shoes men","red","M",4345,2017-09-18,5473 50,"DMQY-K",2017-09-21,"A","2017 pants men","red","37",28,2017-09-25,58,"good","good","good" 80,"GKLW-l",2017-09-22,"A","2017 Jeans Men","red","39",58,2017-09-25,72,"Very comfortable." 30,"HWEC-L",2017-09-23,"A","2017 shoes women","red","M",403,2017-09-26,607,"good!" 40,"IQPD-M",2017-09-24,"B","2017 new pants Women","red","M",35,2017-09-27,52,"very good." 50,"LPEC-N",2017-09-25,"B","2017 dress Women","red","M",29,2017-09-28,47,"not good at all." 60,"NQAB-O",2017-09-26,"B","2017 jacket women","red","S",69,2017-09-29,70,"It's beautiful." 70,"HWNB-P",2017-09-27,"B","2017 jacket women","red","L",30,2017-09-30,55,"I like it so much" 80,"JKHU-Q",2017-09-29,"C","2017 T-shirt","red","M",90,2017-10-02,82,"very good." 使用root账户登录已创建好的ECS,执行以下命令创建数据源文件目录。 mkdir -p /input_data 使用文件传输工具,将以上数据文档上传到ECS的/input_data目录下。
  • 步骤五:准备DWS对接Flink工具dws-connector-flink dws-connector-flink是一款基于DWS JDBC接口实现对接Flink的一个工具。在配置 DLI 作业阶段,将该工具及依赖放入Flink类加载目录,提升Flink作业入库DWS的能力。 浏览器访问https://mvnrepository.com/artifact/com.huaweicloud.dws。 在软件列表中选择最新版本的DWS Connectors Flink,本实践选择DWS Connector Flink 2 12 1 12。 单击“1.0.4”分支,实际请以官网发布的新分支为准。 单击“View ALL”。 单击dws-connector-flink_2.12_1.12-1.0.4-jar-with-dependencies.jar,下载到本地。 创建OBS桶,本实践桶名设置为obs-flink-dws,并将此文件上传到OBS桶下,注意桶也保持与DLI在一个区域下,本实践为“ 华北-北京四”。 图13 上传jar包到OBS桶
  • 调优后表的评估 加载时间减少了24.7%。 分布方式对加载的影响明显,Hash分布方式提升加载效率,Replication分布方式会降低加载效率。在CPU和I/O均充足的情况下,压缩级别对加载效率影响不大。通常,列存表的加载效率比行存要高。 存储占用减少了64.3%。 压缩级别、列存和Hash分布均能够节省存储空间。Replication表会明显加大存储占用,但是可以减小网络开销。通过对小表采用Replication方式,是使用小量空间换取性能的正向做法。 查询性能(速度)提升了54.4%,即查询时间减少了54.4%。 查询性能方面的提升源于对存储方式、分布方式和分布列的优化。在多字段表,统计分析类查询场景下,列存可以提升查询性能。对于Hash分布表,在读/写数据时可以利用各个节点的IO资源,提升表的读/写速度。 重写查询和配置工作负载管理 (WLM) 通常可进一步提升查询性能。有关更多信息,请参阅优化查询性能概述。 基于调优表实践的具体步骤,您可以进一步应用“基于表结构设计和调优提升GaussDB(DWS)查询性能”中的优秀实践方法来改进表的分配,以达到您所期望的数据加载、存储和查询方面的效果。
  • 清除资源 在完成本次实践之后,应删除集群。 如果需要保留集群,删除SS表,请执行以下命令。 1 2 3 4 5 6 7 8 9 10 11 DROP TABLE store_sales; DROP TABLE date_dim; DROP TABLE store; DROP TABLE item; DROP TABLE time_dim; DROP TABLE promotion; DROP TABLE customer_demographics; DROP TABLE customer_address; DROP TABLE household_demographics; DROP TABLE customer; DROP TABLE income_band;
  • 准备工具 迁移过程需准备的工具包括:PL/SQL Developer、Instant Client和DSC,下载地址参见表1 表1 准备工具 工具名 描述 下载地址 PL/SQL Developer Oracle可视化开发工具 PL/SQL Developer下载地址 Oracle Instant Client Oracle客户端 Instant Client下载地址 DSC 配套DWS的语法迁移工具 DSC下载地址 父主题: 使用CDM迁移Oracle数据至GaussDB(DWS)集群
  • 选择表模型 在设计数据仓库模型的时候,最常见的有两种:星型模型与雪花模型。选择哪一种模型需要根据业务需求以及性能的多重考量来定。 星型模型由包含数据库核心数据的中央事实数据表和为事实数据表提供描述性属性信息的多个维度表组成。维度表通过主键关联事实表中的外键。如图1。 所有的事实都必须保持同一个粒度。 不同的维度之间没有任何关联。 图1 星型模型 雪花模型是在基于星型模型之上拓展来的,每一个维度可以再扩散出更多的维度,根据维度的层级拆分成颗粒度不同的多张表。如图2。 优点是减少维度表的数据量,各个维度表之间按需关联。 缺点是需要额外维护维度表的数量。 图2 雪花模型 本实践基于TPC-DS的SS(Store Sales)模型做验证。该模型为雪花模型,图3显示了该数据模型的结构。 图3 TPC-DS Store Sales ER-Diagram 有关该模型中事实表Store_Sales及各维度表的信息,请查阅TPC-DS官方文档:http://www.tpc.org/tpc_documents_current_versions/current_specifications5.asp。 父主题: 基于表结构设计和调优提升GaussDB(DWS)查询性能
共100000条