一位客户来向我们求助,让我们帮助其来扩展和修改它们的 Amazon Redshift 集群。在响应它们请求的过程中,我们利用了 AWSLabs GitHub 仓库中可用的若干种工具。下面就解释了你可以如何像我们那样使用其中的一些工具(这并不是想详细地描述那个文库的内容)。
那位客户正在收购另一家比它自身规模稍小的生产企业。两家企业都有一个BI基础设施,它们相信,将各自的平台进行联合将会降低成本,简化操作。它们想将被收购组织的仓库搬到现有的Amazon Redshift集群中,但是还有一个新的要求。由于被收购企业一些项目的性质,它们有一项加密数据的合同义务。
Amazon Redshift支持静态数据加密,数据库中数据的加密,以及关联快照的加密。要启动加密功能,在创建数据库时必须选择加密。要想在数据库创建后加密数据库,必须建立一个新的数据库,将内容从未加密集群搬移到新集群,在新集群中对内容进行加密。
将你的应用的数据表内容搬移是很简单的,因为Amazon Redshift提供了实现这种目标的一个UNLOAD特性。
要想确定待卸载的数据表,考虑运行如下所示的一个查询命令:
SELECT tablename FROM pg_tables WHERE schemaname = ‘public’;
注意,模式名称需要被扩展来反映你在集群的何处创建了对象。在源集群中运行UNLOAD,在新集群中进行拷贝就可以迁移应用数据了。相当简单!
UNLOAD ('SELECT * FROM sample_table') TO 's3://mybucket/sample/sample_Table_' credentials 'aws_access_key_id=<em><access-key-id></em>;aws_secret_access_key=<em><secret-access-key></em>' manifest;
该命令将一个SELECT语句的结果拆分成一组文件,每个节点一个或多个文件,简化了数据的平行重载过程。它也创建了一个清单文件,可确保COPY命令向加密集群中加载了所有的必须文件,而且只是必须的文件。在COPY命令中使用清单文件是一种推荐的做法。
你仍然可以使用Amazon Redshift Unload/Copy utility(Amazon Redshift卸载/复制工具)将这一过程继续简化。这一工具将数据从源集群中导出到S3中的一个位置,使用Amazon KMS服务对数据进行加密。它也可以将数据导入到另一Amazon Redshift集群中,并清除S3中的数据。
对很多应用来讲,Amazon Redshift包含的不仅仅是应用数据。Amazon Redshift支持创建数据库用户,用户组,和向用户和用户组分配特权。准确地重新创建这些数据可能是易出错的,除非所有数据都使用脚本进行创建,且每个脚本都是受源代码控制的。幸运的是,创建脚本,直接从源集群迁移这些数据,在加密集群中运行这些脚本来复制你所需的数据,是非常简单的。
在实际创建脚本前,我们开始的最佳位置就是AWSLabs GitHub仓库。在AdminViews目录中,已经有若干有用的脚本。你可以为模式,数据表,和视图创建DDL。你也可以按用户获取模式,视图和表特权清单,查看用户所属的用户组。所有这些都是有用的信息,但是你想做的是,在你的源数据库中创建SQL语句,并在你的新的加密数据库中执行这些语句。
你可以如下图所示,从pg_user表中获取用户列表:
SELECT 'CREATE USER '|| usename || ';' FROM pg_user WHERE usename <> 'rdsdb'; Produces: CREATE USER acctowner; CREATE USER mrexample; CREATE USER counterexample; CREATE USER mrspremise; CREATE USER mrsconclusion;
你应该向你创建的账户分配密码。没有方法用来从源数据库中提取现有的密码,所以必须创建新的密码。
从GitHub下载代码,展开src目录,在AdminViews目录中找到脚本。在你的Amazon Redshift集群中创建一个名为admin的模式,运行每一个以v_开始的脚本来创建视图。你可以如下所示,用SQL语句访问创建的视图:
SELECT * FROM admin.v_generate_schema_ddl; Schema name: Admin ddl: Create schema admin
运行v_generate_group_DDL.SQL脚本,在新数据库中创建用户组:
SELECT 'CREATE GROUP '|| groname ||';' FROM pg_group; Produces: CREATE GROUP chosen; CREATE GROUP readonly;
用户归属于用户组。你可以使用v_get_users-in_group脚本获取这些关联:
SELECT 'ALTER GROUP ' ||groname||' ADD USER '||usename||';' FROM admin.v_get_users_in_group; Produces: ALTER GROUP chosen ADD USER mrsconclusion; ALTER GROUP readonly ADD USERmrexample; ALTER GROUP readonly ADD USERmrspremise;
可以运行适当的脚本直接从脚本中生成模式,视图和数据表DDL:
v_generate_schema_DDL.SQL, v_generate_table_DDL.SQL v_generate_view_DDL.SQL
你需要在新数据库中为每个模式设置适当的特权。你可以运行如下脚本,在现有数据库中获取相关的信息:
SELECT * FROM admin.v_get_schema_priv_by_user WHERE schemaname NOT LIKE 'pg%' AND schemaname <> 'information_schema' AND usename <> 'johnlou' AND usename <> 'rdsdb';
在这里你可以看到赋予每个用户的多个不同权限,这些用户已经被赋予了模式特权。想要创建运行于新数据库中的SQL,你可以使用一个UDF(用户定义的函数)为结果集合中的每一行创建一系列特权。下面展示了创建该函数的一种方法:
create function f_schema_priv_granted(cre boolean, usg boolean) returns varchar STABLE AS $ priv = '' if cre: priv = str('create') if usg: priv = priv + str(', usage') return priv $LANGUAGE plpythonu
f_schema_priv_granted函数返回了一系列串联权限。在查询命令中运行该函数来生成包含GRANT语句的SQL:
SELECT 'GRANT '|| f_schema_priv_granted(cre, usg) ||' ON schema '|| schemaname || ' TO ' || usename || ';' FROM admin.v_get_schema_priv_by_user WHERE schemaname NOT LIKE 'pg%' AND schemaname <> 'information_schema' AND usename <> 'rdsdb'; Produces GRANT CREATE, USAGE ON schema public TO mrexample; GRANT CREATE, USAGE ON schema public TO counterexample; GRANT CREATE, USAGE ON schema public TO mrspremise; GRANT CREATE, USAGE ON schema public TO o mrsconclusion;
作为另一种选择,如果你喜欢CASE语句胜过UDF,或者不习惯python,你可以写类似下面的内容:
SELECT 'grant '|| concat(CASE WHEN cre is true THEN 'create' else ' ' END, CASE WHEN usg is true THEN ', usage' ELSE ' ' END ) || ' ON schema '|| schemaname || ' TO ' || usename || ';' FROM admin.v_get_schema_priv_by_user WHERE schemaname NOT LIKE 'pg%' AND schemaname <> 'information_schema' AND schemaname <> 'public' AND usg = 'true';
相似地,UDF可用于创建一系列权限,这些权限在每一个视图和表中用于GRANT语句中。有一个更广范围的特权:SELECT,INSERT,UPDATE,DELETE,和REFERENCES。UDF与下面所示的类似:
create function f_table_priv_granted(sel boolean, ins boolean, upd boolean, delc boolean, ref boolean) returns varchar STABLE AS $ priv = '' if sel: priv = str('select') if ins: priv = priv + str(', insert') if upd: priv = priv + str(', update') if delc: priv = priv + str(', delete') if ref: priv = priv + str(', references ') return priv $LANGUAGE plpythonu
注意,在该函数中,第四句语句未匹配视图中的任何一列。Del使用时要结合其他对象,因为它是一个保留字 。同时也请注意,如果你不喜欢使用UDF,你也可以使用CASE语句构造一个具有相同功能的SQL语句。
你可以使用下面的查询命令为数据表生成特权
SELECT 'GRANT '|| f_table_priv_granted(sel, ins, upd, del, ref) || ' ON '|| schemaname||'.'||tablename ||' TO '|| usename || ';' FROM admin.v_get_tbl_priv_by_user WHERE schemaname NOT LIKE 'pg%' AND schemaname <> 'information_schema' AND usename <> 'rdsdb'; Produces: GRANT SELECT on public.old_sample to mrexample; GRANT SELECT ON public.old_sample TO mrspremise; GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON public.old_sample TO mrsconclusion; GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON public.sample TO mrexample; GRANT SELECT ON public.sample to mrspremise;
类似地,运行下面的查询命令为视图生成特权:
SELECT 'GRANT '|| f_table_priv_granted(sel, ins, upd, del, ref) || ' ON '|| schemaname||'.'||tablename ||' TO '|| usename || ';' FROM admin.v_get_view_priv_by_user WHERE schemaname NOT LIKE 'pg%' AND schemaname <> 'information_schema' AND usename <> 'rdsdb'; Produces: GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON public.loadview TO johnlou; GRANT SELECT, INSERT, UPDATE, DELETE, REFERENCES ON public.my_sample_view TO johnlou;
仓库中的脚本使迁移元数据到新的加密集群变得更简单。在将数据表从被收购公司的仓库搬移到Amazon Redshift中的一个独立模式后,还有其他的几个脚本也被证明是非常有用的。
原文链接 : https://blogs.aws.amazon.com/bigdata/post/Tx3L6LQQ1Q6XXTK/Migrating-Metadata-when-Encrypting-an-Amazon-Redshift-Cluster
活动推荐: AWS Summit AWS技术峰会2015(上海)
AWS因云而变创业大赛
2015云届先锋女性论坛
( 翻译/吕冬梅 责编/王鑫贺 )
订阅“AWS中文技术社区”微信公众号,实时掌握AWS技术及产品消息!
AWS中文技术社区为广大开发者提供了一个Amazon Web Service技术交流平台 ,推送AWS最新资讯、技术视频、技术文档、精彩技术博文等相关精彩内容,更有AWS社区专家与您直接沟通交流!快加入AWS中文技术社区,更快更好的了解AWS云计算技术。