CREATE <object> ... CLONE¶
创建系统中现有对象的副本。该命令主要用于创建数据库、架构和表的 零副本克隆,但是,也可以用于快速/轻松地创建其他架构对象的克隆,例如外部暂存区、文件格式和序列以及数据库角色。
该命令是特定于对象的 CREATE <object> 命令的变体,增加了 CLONE
关键字。
使用 Time Travel 克隆对象¶
对于数据库、架构和非临时表,CLONE
支持额外的 AT | BEFORE
子句来使用 Time Travel 进行克隆。
对于数据库和架构,CLONE
支持 IGNORE TABLES WITH INSUFFICIENT DATA RETENTION 参数跳过已从 Time Travel 中清除的任何表(例如,数据保留期为一天的瞬态表)。
语法¶
数据库、架构¶
CREATE [ OR REPLACE ] { DATABASE | SCHEMA } [ IF NOT EXISTS ] <object_name>
CLONE <source_object_name>
[ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
[ IGNORE TABLES WITH INSUFFICIENT DATA RETENTION ]
...
表¶
CREATE [ OR REPLACE ] TABLE [ IF NOT EXISTS ] <object_name>
CLONE <source_object_name>
[ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
...
动态表¶
CREATE [ OR REPLACE ] DYNAMIC TABLE <name>
CLONE <source_dynamic_table>
[ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
[
TARGET_LAG = { '<num> { seconds | minutes | hours | days }' | DOWNSTREAM }
WAREHOUSE = <warehouse_name>
]
事件表¶
CREATE [ OR REPLACE ] EVENT TABLE <name>
CLONE <source_event_table>
[ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ]
数据库角色¶
CREATE [ OR REPLACE ] DATABASE ROLE [ IF NOT EXISTS ] <database_role_name>
CLONE <source_database_role_name>
其他架构对象¶
CREATE [ OR REPLACE ] { ALERT | FILE FORMAT | SEQUENCE | STAGE | STREAM | TASK }
[ IF NOT EXISTS ] <object_name>
CLONE <source_object_name>
...
Time Travel 参数¶
{ AT | BEFORE } ( { TIMESTAMP => timestamp | OFFSET => time_difference | STATEMENT => id } )
AT | BEFORE 子句接受以下参数之一:
TIMESTAMP => timestamp
指定要用于 Time Travel 的确切日期和时间。该值必须显式转换为 TIMESTAMP。
OFFSET => time_difference
指定自当前时间开始的、要用于 Time Travel 的时间差值(以秒为单位),其格式为
-N
,其中N
可以是整数或算术表达式(例如,-120
为 120 秒、-30*60
为 1800 秒或 30 分钟)。STATEMENT => id
指定要用作 Time Travel 参考点的语句的查询 ID。此参数支持以下某一类型的任意语句:
DML(例如 INSERT、UPDATE、DELETE)
TCL(BEGIN、COMMIT 事务)
SELECT
查询 ID 必须引用过去 14 天内执行的查询。如果查询 ID 引用的查询超过 14 天,则返回以下错误:
Error: statement <query_id> not found
若要解决此限制,请使用引用查询的时间戳。
IGNORE TABLES WITH INSUFFICIENT DATA RETENTION
忽略在 Time Travel 中不再具有可供克隆的历史数据的表。如果 AT | BEFORE 子句中指定的过去时间超出了数据库或架构中任何子表的数据保留期,则跳过子表的克隆操作。有关更多信息,请参阅 子对象和数据保留时间。
一般使用说明¶
克隆是可以写入的,并且独立于其源(即,对源或克隆所做的更改不会反映在另一个对象中)。
针对源数据库、架构或表显式设置的参数将保留在从源容器或子对象创建的任何克隆中。
要创建克隆,当前角色必须对源对象具有以下权限:
- 数据库角色:
对数据库角色的 OWNERSHIP 和对目标数据库的 CREATE DATABASE ROLE 权限。
- 架构:
如果指定 WITH MANAGED ACCESS 子句中,所需的权限取决于源架构是托管架构还是非托管架构。有关详细信息,请参阅 CREATE SCHEMA 权限。
- 表:
SELECT
- 警报、管道、流、任务:
OWNERSHIP
- 其他对象:
USAGE
此外,要克隆架构或架构中的对象,当前角色必须对源和克隆的容器对象具有所需的权限。
对于数据库角色:
数据库角色在您运行 CREATE DATABASE ...CLONE 命令克隆数据库时进行克隆。但是,如果克隆其他数据库对象(如架构或表),则数据库中的数据库角色不会与架构或表一起克隆。
如果数据库角色已克隆到目标数据库,则该命令将失败。如果发生这种情况,请从目标数据库中弃用数据库角色,然后重试 CLONE 命令。
对于数据库和架构,克隆是递归的:
克隆数据库将克隆数据库中的所有架构和其他对象。
克隆架构将克隆架构中包含的所有对象。
但是,不会 克隆以下对象类型:
外部表
内部 (Snowflake) 暂存区
对于数据库、架构和表,在对克隆执行修改现有数据或添加新数据的操作之前,克隆 不会 对对象的整体数据存储产生影响,例如:
添加、删除或修改克隆表中的行。
在克隆的架构中创建新的填充表。
克隆表会复制源表的结构、数据和某些其他属性(如
STAGE FILE FORMAT
)。但是:
克隆的表 不 包括源表的加载历史记录。这样做的一个结果是,加载到源表中的数据文件可以再次加载到其克隆中。
尽管克隆的表会复制源表的群集密钥,但新表开始时自动聚类已挂起,即使源表的自动聚类未挂起也是如此。
CREATE TABLE ... CLONE 和 CREATE EVENT TABLE ... CLONE 语法包括 COPY GRANTS 关键字,这些关键字对新表克隆的影响如下:
如果使用了 COPY GRANTS 关键字,则新对象将继承对原始表授予的任何显式访问权限,但 :emph:` 不会 ` 继承将来为架构中的对象类型定义的任何权限。
如果 未 使用 COPY GRANTS 关键字,则新对象克隆不会继承对原始表授予的任何显式访问权限,但会继承在架构中为该对象类型定义的任何未来权限(使用 GRANT <privileges> ...ON FUTURE 语法。)
备注
如果语句要替换同名的现有表,则从要替换的表中复制授权。如果没有该名称的现有表,则从要克隆的源表中复制授权。
关于元数据:
注意
客户应确保在使用 Snowflake 服务时,不会将个人数据(用户对象除外)、敏感数据、出口管制数据或其他受监管数据作为元数据输入。有关更多信息,请参阅 Snowflake 中的元数据字段。
CREATE OR REPLACE <object> 语句是原子的。也就是说,当对象被替换时,旧对象将被删除,新对象将在单个事务中创建。
适用于克隆对象的其他规则¶
- 元数据:
对象克隆继承执行 CREATE <object> CLONE 语句时或过去使用 Time Travel 指定的时间/点时当前源对象的 名称 和 结构。无论是否使用 Time Travel,对象克隆都会继承执行语句时源对象当前的其他元数据,例如注释或表群集密钥。
- 子对象:
数据库或架构克隆包括在执行语句时或过去指定时间/点处于活动状态的所有子对象。表数据的快照表示执行语句时或过去指定时间/点的源数据状态。子对象在执行语句时继承源子对象的名称和结构。
- 未克隆:
克隆数据库或架构 不会 克隆数据库或架构中以下类型的对象:
外部表
内部 (Snowflake) 暂存区
- 管道:
数据库或架构克隆仅包含引用外部(Amazon S3、Google Cloud Storage 或 Microsoft Azure)暂存区的管道对象;不会克隆内部 (Snowflake) 管道。
管道克隆的默认状态如下所示:
如果显示
AUTO_INGEST = FALSE
,则克隆的管道默认处于暂停状态。如果显示
AUTO_INGEST = TRUE
,则克隆的管道已设置为STOPPED_CLONED
状态。在此状态下,管道不会因为新暂存文件而累积事件通知。当管道显式恢复时,它仅处理因新事件通知而触发的数据文件。
各种状态下的管道克隆都可以恢复,方法是执行 ALTER PIPE ... RESUME 语句。
- 标签:
克隆数据库或架构会对该数据库或架构中的 标签 产生如下影响:
源对象(例如表)中的标签关联保存在克隆的对象中。
对于数据库或架构:
也会克隆存储在该数据库或架构中的标签。
克隆数据库或架构时,也会克隆保留在该架构或数据库中的标签。
如果表或视图存在于源架构/数据库中,并且引用了同一架构或数据库中的标签,则克隆的表或视图将映射到相应的克隆标签(在目标架构/数据库中),而不是源架构或数据库中的标签。
- Java UDF:
当克隆包含 Java UDF 的数据库或架构时,可以克隆 Java UDF。Java UDF 必须满足某些条件才能被克隆。有关更多信息,请参阅 克隆的限制。
- 表数据:
克隆数据库、架构或表时,将创建每个表中数据的快照,并将其提供给克隆。快照表示执行语句时或过去指定时间/点(使用 Time Travel)的源数据状态。
- 对象引用:
视图、流和任务等对象在其定义中包含对象引用。例如:
视图包含包括表引用的存储查询。
流指向源表。
任务或警报调用存储过程或执行引用其他对象的 SQL 语句。
当克隆这些对象中的一个时,无论是在克隆的数据库或架构中,还是作为单个对象,对于那些支持克隆的对象类型,克隆都会从源对象的定义中继承对其他对象的引用。例如,视图的克隆从源视图继承存储的查询,包括查询中的表引用。
密切注意源对象定义中的任何对象名称是完全限定的还是部分限定的。完全限定名称包括数据库和架构名称。源对象的任何克隆都包含在其自己的定义中。
例如:
-- Create a schema to serve as the source for a cloned schema. CREATE SCHEMA source; -- Create a table. CREATE TABLE mytable (col1 string, col2 string); -- Create a view that references the table with a fully-qualified name. CREATE VIEW myview AS SELECT col1 FROM source.mytable; -- Retrieve the DDL for the source schema. SELECT GET_DDL ('schema', 'source', true); +--------------------------------------------------------------------------+ | GET_DDL ('SCHEMA', 'SOURCE', TRUE) | |--------------------------------------------------------------------------| | create or replace schema MPETERS_DB.SOURCE; | | | | create or replace TABLE MPETERS_DB.SOURCE.MYTABLE ( | | COL1 VARCHAR(16777216), | | COL2 VARCHAR(16777216) | | ); | | | | CREATE VIEW MPETERS_DB.SOURCE.MYVIEW AS SELECT col1 FROM source.mytable; | | | +--------------------------------------------------------------------------+ -- Clone the source schema. CREATE SCHEMA source_clone CLONE source; -- Retrieve the DDL for the clone of the source schema. -- The clone of the view references the source table with the same fully-qualified name -- as in the view in the source schema. SELECT GET_DDL ('schema', 'source_clone', true); +--------------------------------------------------------------------------------+ | GET_DDL ('SCHEMA', 'SOURCE_CLONE', TRUE) | |--------------------------------------------------------------------------------| | create or replace schema MPETERS_DB.SOURCE_CLONE; | | | | create or replace TABLE MPETERS_DB.SOURCE_CLONE.MYTABLE ( | | COL1 VARCHAR(16777216), | | COL2 VARCHAR(16777216) | | ); | | | | CREATE VIEW MPETERS_DB.SOURCE_CLONE.MYVIEW AS SELECT col1 FROM source.mytable; | | | +--------------------------------------------------------------------------------+
如果打算将视图指向 其他 数据库或架构中具有相同名称的表,我们建议创建一个新视图,而不是克隆现有视图。本指南还适用于在其定义中引用对象的其他对象。
备注
某些限制适用于克隆操作。例如,在克隆操作期间影响源对象的 DDL 语句可能会改变结果或导致错误。
克隆不是即时的,特别是对于大型对象(数据库、架构、表),并且不会锁定要克隆的对象。因此,当克隆操作仍在运行时,克隆不会反映应用于表数据的任何 DML 语句(如果适用)。
有关此用例以及可能影响克隆操作的其他用例的详细信息,请参阅 克隆注意事项。
使用 Time Travel 进行克隆的注意事项(仅限数据库、架构、表和事件表)¶
AT | BEFORE 子句克隆过去指定时间或基于指定 SQL 语句的数据库、架构或表:
AT
关键字指定请求包含时间戳等于指定参数的语句或事务所做的任何更改。BEFORE
关键字指定请求引用紧挨着指定参数之前的点。
使用
STATEMENT
克隆相当于使用TIMESTAMP
,其值等于 SQL 语句(或其包含的事务)的记录执行时间,由指定的语句 ID 标识。如果出现以下情况,则返回错误:
在过去 AT | BEFORE 子句中指定的时间点上不存在要克隆的对象。
克隆对象或其任何子对象(例如克隆架构或数据库中的表)所需的历史数据已被清除。
作为已从 Time Travel 中清除的子对象的解决方法,请使用 IGNORE TABLES WITH INSUFFICIENT DATA RETENTION 参数,该参数属于 CREATE <object> ...CLONE 命令。有关更多信息,请参阅 子对象和数据保留时间。
如果克隆的数据库或架构中的任何子对象在 AT | BEFORE 子句中指定的过去的时间点不存在,则不会克隆该子对象。
有关更多信息,请参阅 了解和使用 Time Travel。
排查使用 Time Travel 克隆对象时出现的问题¶
以下方案可帮助您排查在使用 Time Travel 克隆对象时可能出现的问题。
错误 |
000707 (02000): Time travel data is not available for <object_type>
<object_name>. The requested time is either beyond the allowed time
travel period or before the object creation time.
|
---|
由于以下原因,可能会返回此错误:
原因 |
AT | BEFORE 子句指定的过去时间超出了对象的数据保留期。 |
---|---|
解决方案 |
使用适当的 SHOW <objects> 命令和 |
原因 |
如果任何子对象的历史数据已移出 Time Travel,则数据库或架构的克隆操作将失败。 |
---|---|
解决方案 |
要跳过 Time Travel 中不再具有历史数据的子表,请使用 IGNORE TABLES WITH INSUFFICIENT DATA RETENTION 参数执行语句克隆来跳过这些表。 |
原因 |
在某些情况下,这是由于使用需要时间戳的字符串引起的。 |
---|---|
解决方案 |
将字符串转换为时间戳。 ... AT(TIMESTAMP => '2023-12-31 12:00:00') -- fails
... AT(TIMESTAMP => '2023-12-31 12:00:00'::TIMESTAMP) -- succeeds
|
示例¶
克隆数据库和数据库中当前状态的所有对象:
CREATE DATABASE mytestdb_clone CLONE mytestdb;
克隆当前状态的架构和架构中的所有对象:
CREATE SCHEMA mytestschema_clone CLONE testschema;
克隆当前状态的表:
CREATE TABLE orders_clone CLONE orders;
克隆指定时间戳中日期和时间之前存在的架构:
CREATE SCHEMA mytestschema_clone_restore CLONE testschema BEFORE (TIMESTAMP => TO_TIMESTAMP(40*365*86400));
克隆在指定时间戳的日期和时间存在的表:
CREATE TABLE orders_clone_restore CLONE orders AT (TIMESTAMP => TO_TIMESTAMP_TZ('04/05/2013 01:02:03', 'mm/dd/yyyy hh24:mi:ss'));
克隆在执行指定语句(即查询 ID)之前就存在的表:
CREATE TABLE orders_clone_restore CLONE orders BEFORE (STATEMENT => '8e5d0ca9-005e-44e6-b858-a8f5b37c5726');
克隆数据库及其所有对象四天前的状态,并跳过任何数据保留期少于四天的任何表:
CREATE DATABASE restored_db CLONE my_db AT (TIMESTAMP => DATEADD(days, -4, current_timestamp)::timestamp_tz) IGNORE TABLES WITH INSUFFICIENT DATA RETENTION;