执行深层复制 - Amazon Redshift

执行深层复制

深层复制将使用批量插入重新创建和重新填充表,这将自动对表进行排序。如果表具有大型未排序区域,则深层复制比 vacuum 快得多。如果您可以跟踪并发更新,我们建议您仅在深层复制操作期间进行并发更新。该过程完成后,将增量更新移到新表中。VACUUM 操作支持自动并发更新。

您可以选择四种方法之一来创建原始表的副本:

  • 使用原始表 DDL。

    如果 CREATE TABLE DDL 可用,那么这是最快且首选的方法。在创建新表时,您可以指定所有表和列属性,包括主键和外键。

    注意

    如果原始 DDL 不可用,您可以通过运行名为 v_generate_tbl_ddl 的脚本来重新创建该 DDL。您可以从 amazon-redshift-utils(这是 Amazon Web Services - Labs GitHub 存储库的一部分)下载该脚本。

  • 使用 CREATE TABLE LIKE。

    如果原始 DDL 不可用,您可以使用 CREATE TABLE LIKE 来重新创建原始表。新表继承父表的编码、分配键、排序键和 not-null 属性。新表不继承父表的主键和外键属性,但您可以使用 ALTER TABLE 来添加它们。

  • 创建一个临时表并截断原始表。

    如果您必须保留父表的主键和外键属性。如果父表有依赖关系,您可以使用 CREATE TABLE ... AS (CTAS) 以创建临时表。然后,截断原始表并从临时表填充它。

    与使用永久表相比,使用临时表可极大地提高性能,但存在丢失数据的风险。在创建临时表的会话结束时将自动删除该临时表。TRUNCATE 将立即提交,即使它在事务块中。如果 TRUNCATE 成功,但会话在接下来的 INSERT 完成前关闭,则数据将丢失。如果数据丢失是不可接受的,请使用永久表。

创建表的副本后,您可能必须授予对新表的访问权限。您可以使用 GRANT 来定义访问权限。要查看和授予表的所有访问权限,您必须是以下人员之一:

  • 超级用户。

  • 您想复制的表的拥有者。

  • 拥有 ACCESS SYSTEM TABLE 权限以查看表的权限且具有所有相关权限的授予权限的用户。

此外,您可能必须授予对于深层复制所在模式的使用权限。如果您的深层复制的模式与原始表的模式不同,也不是 public 模式,则授予使用权限是必需的。要查看和授予使用权限,您必须是以下人员之一:

  • 超级用户。

  • 可以授予对深层复制模式的 USAGE 权限的用户。

使用原始表 DDL 执行深层复制
  1. (可选)通过运行名为 v_generate_tbl_ddl 的脚本来重新创建表 DDL。

  2. 使用原始 CREATE TABLE DDL 创建表的副本。

  3. 使用 INSERT INTO … SELECT 语句向副本填充原始表中的数据。

  4. 检查所授予的对于旧表的权限。您可以在 SVV_RELATION_PRIVILEGES 系统视图中查看这些权限。

  5. 如有必要,将旧表的权限授予新表。

  6. 向在原始表中具有权限的每个组和用户授予使用权限。如果您的深层复制表处于 public 模式,或者与原始表处于同一模式,则无需执行此步骤。

  7. 删除原始表。

  8. 使用 ALTER TABLE 语句将副本重命名为原始表名称。

以下示例使用名为 sample_copy 的 SAMPLE 的副本对 SAMPLE 表执行深层复制。

--Create a copy of the original table in the sample_namespace namespace using the original CREATE TABLE DDL. create table sample_namespace.sample_copy ( … ); --Populate the copy with data from the original table in the public namespace. insert into sample_namespace.sample_copy (select * from public.sample); --Check SVV_RELATION_PRIVILEGES for the original table's privileges. select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type; --Grant the original table's privileges to the copy table. grant DELETE on table sample_namespace.sample_copy to group group1; grant INSERT, UPDATE on table sample_namespace.sample_copy to group group2; grant SELECT on table sample_namespace.sample_copy to user1; grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy to user2; --Grant usage permission to every group and user that has privileges in the original table. grant USAGE on schema sample_namespace to group group1, group group2, user1, user2; --Drop the original table. drop table public.sample; --Rename the copy table to match the original table's name. alter table sample_namespace.sample_copy rename to sample;
使用 CREATE TABLE LIKE 执行深层复制
  1. 使用 CREATE TABLE LIKE 创建新表。

  2. 使用 INSERT INTO … SELECT 语句将当前表中的行复制到新表。

  3. 检查所授予的对于旧表的权限。您可以在 SVV_RELATION_PRIVILEGES 系统视图中查看这些权限。

  4. 如有必要,将旧表的权限授予新表。

  5. 向在原始表中具有权限的每个组和用户授予使用权限。如果您的深层复制表处于 public 模式,或者与原始表处于同一模式,则无需执行此步骤。

  6. 删除当前表。

  7. 使用 ALTER TABLE 语句将新表重命名为原始表名称。

以下示例使用 CREATE TABLE LIKE 对 SAMPLE 表执行深层复制。

--Create a copy of the original table in the sample_namespace namespace using CREATE TABLE LIKE. create table sameple_namespace.sample_copy (like public.sample); --Populate the copy with data from the original table. insert into sample_namespace.sample_copy (select * from public.sample); --Check SVV_RELATION_PRIVILEGES for the original table's privileges. select * from svv_relation_privileges where namespace_name = 'public' and relation_name = 'sample' order by identity_type, identity_id, privilege_type; --Grant the original table's privileges to the copy table. grant DELETE on table sample_namespace.sample_copy to group group1; grant INSERT, UPDATE on table sample_namespace.sample_copy to group group2; grant SELECT on table sample_namespace.sample_copy to user1; grant INSERT, SELECT, UPDATE on table sample_namespace.sample_copy to user2; --Grant usage permission to every group and user that has privileges in the original table. grant USAGE on schema sample_namespace to group group1, group group2, user1, user2; --Drop the original table. drop table public.sample; --Rename the copy table to match the original table's name. alter table sample_namespace.sample_copy rename to sample;
通过创建临时表并截断原始表来执行深层复制
  1. 使用 CREATE TABLE AS 创建具有原始表中的行的临时表。

  2. 截断当前表。

  3. 使用 INSERT INTO … SELECT 语句将临时表中的行复制到原始表。

  4. 删除临时表。

以下示例通过创建临时表并截断原始表来对 SALES 表执行深层复制。由于原始表仍然存在,因此您无需授予对副本表的权限。

--Create a temp table copy using CREATE TABLE AS. create temp table salestemp as select * from sales; --Truncate the original table. truncate sales; --Copy the rows from the temporary table to the original table. insert into sales (select * from salestemp); --Drop the temporary table. drop table salestemp;