Backups for disaster recovery and immutable storage

Backups help organizations protect critical data against modification or deletion.

Backups represent discrete snapshots of Snowflake objects. You choose which objects to back up, how frequently to back them up, how long to keep the backups, and whether to add a retention lock so that they can’t be deleted prematurely.

Use cases for Snowflake backups

The following use cases are typical applications of backups:

Regulatory compliance:

Backups with retention lock help organizations, financial institutions, and related industries address regulations that require records to be retained in an immutable format.

Note

Snowflake has engaged Cohasset Associates to perform an independent assessment of our Backups feature for compliance with key regulatory recordkeeping requirements, including SEC 17a-4(f), SEC 18a-6(e), FINRA Rule 4511(c), and CFTC Rule 1.31(c)-(d). This Cohasset assessment provides independent, third-party verification that Snowflake’s immutable storage controls support the creation, protection, and retention of data, and provides customers with confidence that Snowflake meets critical industry standards for regulated data retention subject to the evaluated regulations.

For the full compliance report that applies to Snowflake backups with retention lock, see the Snowflake Compliance Center (https://trust.snowflake.com/resources?s=jv88d2ujxzj9kcnz43w31&name=snowflake-cohasset-assessment).

Recovery:

Backups help organizations create discrete snapshots to protect and recover business-critical data in case of accidental modifications or deletions.

Cyber resilience:

Backups with retention lock are part of an overall cyber-resilience strategy. They help organizations protect business-critical data during cyber attacks, especially ransomware attacks. The retention lock ensures that this data can’t be deleted by the attacker, even if they gain access to the account by using the ACCOUNTADMIN or ORGADMIN roles.

Key concepts

This section provides an overview of the key concepts for backups in Snowflake.

Backup

A backup represents a point-in-time snapshot of an object.

  • The object can be a single table, a schema, or an entire database.

  • A specific backup can be identified by a unique ID generated by Snowflake.

  • A backup can’t be modified. It can, however, be deleted, and the backup expiration period can be modified (unless a retention lock is applied).

During day-to-day operations, you rarely interact with individual backups. Instead, you manage the backup sets that contain them. For example, you get a list of backups by running the SHOW BACKUPS IN BACKUP SET command. You create a new backup by running an ALTER BACKUP SET command.

Backup set

A backup set is a schema-level object that contains a set of backups for a specific database, schema, or table. Snowflake has SQL commands to CREATE, ALTER, DROP, SHOW, and DESCRIBE backup sets.

You can have multiple backup sets for the same object.

The life cycle of the backups within a set is determined by an optional backup policy that you can attach to the backup set. You can also add or delete backups manually in a backup set. Your ability to delete backups is affected by other factors, in particular retention lock and legal hold.

Backup policy

A backup policy is a schema-level object that contains the settings that define the life cycle of the backups within a backup set. These settings include schedule, expiration, and retention lock.

  • The schedule determines when backups are created. The schedule can be defined as an interval in minutes, or as a cron expression. For example, if the schedule is set to one hour, a backup of the object is taken every 60 minutes.

  • The expiration period is the length of time the backup is valid. After a backup expires, Snowflake deletes it automatically, unless a legal hold is applied to that particular backup.

    Tip

    If the backup set doesn’t have a retention lock and the particular backup doesn’t have a legal hold applied, you can delete the backup manually before the end of the expiration period. You can manually delete backups one at a time, always starting with the oldest backup that doesn’t have a legal hold.

Each backup policy must have one or both of the schedule and expiration period properties. For example, you can create a policy with a schedule and an expiration period, and let Snowflake handle all creation and removal of the backups in all backup sets where that policy is applied. Alternatively, you might create a policy with a schedule and no expiration period if you want to manage removing older backups yourself. Or, you can create a policy with an expiration period but without a schedule, and then manage backup creation yourself. You can’t create a policy with no schedule and no expiration period.

If you associate a backup policy with a backup set, you can do so when you create the backup set, or you can apply the policy later. Or, you can have a backup set that doesn’t have an associated backup policy. In that case, you manually control when to take new backups and expire old ones.

You can apply a backup policy to multiple backup sets. If you modify a backup policy, Snowflake applies the changes to all backup sets that the policy is attached to.

Retention lock

A retention lock protects a backup from deletion for the defined expiration period. You can use a backup with a retention lock for backups for regulatory compliance and cyber resilience. The following restrictions apply for a backup set with retention lock:

  • Backups can’t be deleted by any role, including the ACCOUNTADMIN role.

  • You can’t decrease the backup expiration period, although you can increase the expiration period.

  • You can’t drop a backup set if there are any unexpired backups in the set.

  • You can’t drop a schema that contains a backup set with any unexpired backups.

  • You can’t drop a database that contains a backup set with any unexpired backups.

  • You can’t drop an account that contains a database with a backup set that has any unexpired backups.

Important

Applying a backup policy with a retention lock to a backup set is irreversible. Due to the strong guarantees that are needed for regulatory compliance, after you put a retention lock on a backup set, you can’t revoke the lock. Snowflake support also can’t revoke such a retention lock. Plan carefully before you set a retention lock on a backup set with a long expiration period, to avoid unexpected storage charges for undeletable backup sets, and the schemas and databases that contain them.

If a Snowflake organization is deleted, the organization is no longer a Snowflake customer. In this case, Snowflake deletes all backups, including those with retention locks. Deleting a Snowflake organization requires the involvement of Snowflake support. It isn’t something that an administrator can do by accident.

Overview of the backup lifecycle

The following diagram shows how the Snowflake objects, backups, backup sets, and backup policies relate to each other. The diagram involves the simplest kind of backup: one for a single table. Each backup operation produces a new backup. All the backups for that particular object are grouped together in a backup set. The automatic addition and removal of backups in the backup set is governed by the backup policy. To recover the information from a backup, you use a CREATE command to create a new object from a specific backup.

Backups key concepts

How backups work

Backups are zero-copy duplicates of a Snowflake object similar to clones. Backups don’t make copies of table data when they are created. The backup mechanism backs up table data without incurring the additional cost or time of copying the data.

Snowflake stores data in files that are immutable, and maintains pointers from backups to the data files that underlie the table. As the table evolves and is modified, Snowflake ensures that each data file is protected from deletion as long as there is an unexpired backup that references that file.

Restrictions for backups

Snowflake enforces the following restrictions for backups:

  • You can’t modify the retention lock for a backup policy.

  • When a policy has a retention lock, you can increase the expiration period, but you can’t decrease it.

  • The minimum schedule interval for scheduled backups is one hour (60 minutes).

Limitations of backups

Currently, you can create a maximum of two database backup sets for a specific database. Likewise, you can create a maximum of two schema backup sets for a specific schema, and two table backup sets for a specific table. An object might still appear in more than two backup sets. For example, a table might have one or two associated table backup sets. The same table might also be included in one or two schema backup sets, and one or two database backup sets.

Comparison of backups with other disaster recovery and business continuity features

Backups provide the following advantages that are different from other Snowflake business continuity and disaster recovery features, such as replication and Time Travel:

  • You can enable long-term retention for backups. Long-term retention helps with recovery, regulatory compliance, and cyber resilience against threats such as ransomware or insider attacks.

  • Retention lock ensures that backups can’t be deleted by any user, including account administrators.

  • You can schedule backups on a different timeframe than you use for other data transfer operations, such as replication refreshes.

  • You can backup and restore individual table objects, or container objects such as entire schemas or databases.

  • You can prevent the retention time for backups from being reduced after the backup is taken, by using a backup policy that includes a retention lock. That’s different from the Time Travel feature, where you can reduce the retention interval to zero.

  • Unlike Time Travel and Fail-safe, backups preserve data from more types of objects than just tables and table data.

  • The speed and storage efficiency of taking backups is similar to the zero-copy mechanism used for cloning.

  • The way all backups for the same object are grouped into backup sets makes management simpler than if you used clones to implement your own backup mechanism. For example, you don’t have to manage large numbers of objects, devise a naming scheme to keep track of the cloned objects, or implement a scheduling mechanism to delete old clones. Also, unlike with cloned objects, backups can’t be modified after you create them.

  • Each backup represents a single table, schema, or a database as of the specified point in time. backups don’t include account-level objects such as users or roles. Some kinds of tables and other database-level objects aren’t included in schema and database backups. For more information, see backup objects.

  • Backup-related objects are stored in the same cloud service provider (CSP) region as the associated database, schema, or table. For business continuity and disaster recovery scenarios, you typically combine backups with Snowflake account replication. That way, all the backup sets and backup policies can be replicated to a different region or a different CSP and recovered even if there’s an outage affecting the original region or CSP.

  • Backup sets and backup policies can’t be cloned. If you clone a schema or database that contains such objects, they aren’t included in the cloned schema or database.

Backup objects

You can create backup sets for tables, schemas, and databases.

References from tables to other objects

Objects, such as views or functions, can refer to objects outside the schema or database in the backup. To ensure that such references continue functioning after you restore from a backup, use one of the following strategies:

  • If the tables and the other objects that they refer to are all in the same schema or the same database, create a backup set for the entire schema or database. That way, Snowflake restores all the interconnected objects at once when you restore from the backup.

  • If objects in a backup set refer to objects that aren’t included in the backup set, be aware that when a backup is restored, the references from the restored objects point to the original objects from the other database or schema. If you dropped those other objects or changed their properties after taking the backup, you might encounter errors when you access the restored objects.

  • For account-level objects, any references from restored objects always point to the original account-level object. That’s because the account-level objects aren’t part of any backup. For example, a schema backup might contain a secret that refers to a security integration. The security integration is an account-level object and can’t be included in any backup.

Types of objects in database and schema backups

The following table lists the objects that are included in a database or schema backup:

Object

Included in backup

Notes

Permanent tables

Yes

Time Travel information for tables isn’t stored as part of a backup.

Transient tables

Yes

Such tables continue to be transient tables after you restore them. Transient schemas and transient databases also retain the transient property after you restore them.

Temporary tables

No

Temporary tables are session scoped and aren’t included in backups.

Dynamic tables

Yes

Dynamic tables have their own data definition language (DDL) syntax for backups. You can run CREATE BACKUP SET FOR DYNAMIC TABLE and CREATE DYNAMIC TABLE FROM BACKUP SET commands. When you restore a dynamic table from a backup, the table is restored in a suspended state. Snowflake automatically initializes the new table during its first refresh.

External tables

No

Hybrid tables

No

Apache Iceberg™ tables

No

Table constraints

Yes

Event tables

No

Sequences

Yes

Views

Yes

Materialized views

No

Secure views

Yes

File formats

Yes

Internal stages

No

External stages

No

Temporary stages

No

Directory tables

No

Pipes

No

Stored procedures

Yes

SQL, Javascript, Python, Java, and Scala procedures are all supported.

User-defined functions (UDFs)

Yes

SQL, Javascript, Python, Java, and Scala functions are all supported. Both scalar UDFs and user-defined table functions (UDTFs) are included in the backup. Java UDFs in backups have the same requirements as in Limitations on cloning.

Streams

No

Tasks

Yes

Tasks are included in the backup. Tasks restored from a backup are suspended and must be resumed.

Data metric functions (DMFs)

No

Policies

Yes

The following kinds of policies are included in a schema or database backup:

  • Column-level security (masking)

  • Row access policies

  • Tag-based masking policies

If any table included in the backup has any other kind of policy applied (for example an aggregation policy, a projection policy, or a storage lifecycle policy), backup creation fails.

Grants

Yes

If you drop a role, associated ownership grants are transferred to the role that performs the DROP ROLE command. Grants other than ownership are deleted in this case. Therefore, the grants on a restored object might differ from the grants that existed when the backup was created.

Database roles

No

Object tagging

Yes

Alerts

Yes

Network rules

Yes

Github repos

No

Models

No

Model monitors

No

Datasets

No

Notebooks

No

Contacts

No

Cortex search services

No

Dbt projects

No

Image repositories

No

Listings

No

Organization listings

No

Pipes

No

Policy (aggregation)

No

Policy (authentication)

No

Policy (feature)

No

Policy (join)

No

Policy (packages)

No

Policy (password)

No

Policy (privacy)

No

Policy (projection)

No

Policy (session)

No

Provisioned throughput

No

Semantic views

No

Services

No

Streamlits

No

How Snowflake associates objects with their backup sets

When you create a backup set for a database, schema, or table, Snowflake associates the backup set with the internal ID of that database, schema, or table. If you delete the original object, you can’t add any more backups to that backup set. This behavior applies even if you recreate an object with the same name, or replace it with an object that was restored from a backup.

If you instead rename the original object, then you can continue making more backups of it by adding more backups to the same backup set. In that case, the output of SHOW BACKUP SETS changes to reflect the OBJECT_NAME value of the renamed object.

If you want to make backups of a table but you frequently drop and recreate that table, perhaps through CREATE OR REPLACE statements, include it in a backup set for the schema or database that contains the table. That way, you can keep using the same backup set regardless of changes to the table.

When you restore a table from a backup, the restored table starts with a different name than the original. Suppose that you want to completely replace the contents of the original table with the backup data, and continue to use the same backup set for more backups of that same table. In that case, use a TRUNCATE or DELETE statement to remove the contents of the original table, and an INSERT … SELECT statement to copy the data from the restored table. Don’t drop the original table and rename the restored table to the name of the original table.

Backups and encryption

The data within backup sets is protected by the same end-to-end encryption as other Snowflake objects and table data. For more information about Snowflake encryption, see Understanding end-to-end encryption in Snowflake.

Key rotation also applies to the data within backups.

Backups and data lineage

Snowflake doesn’t preserve data lineage metadata with database, schema, and table backups. After you restore an object from a backup, you can’t use Snowsight to view lineage information for the restored data.

Cost for backups

The following table describes charges for backups.

For information about credit consumption, see the Snowflake Service Consumption Table.

Cost component

Description

Billed

Backup compute

Snowflake-managed compute service generates scheduled backup creation and expiration.

Yes

Restore compute

Snowflake-managed warehouses are used to restore objects from backups.

Yes

Backup storage

Snowflake-managed cloud object storage to store backup data.

Billed for bytes retained for backups, similar to bytes retained for clones.

You can monitor costs for backup storage in the TABLE_STORAGE_METRICS view using the RETAINED_FOR_CLONE_BYTES column, and in the BACKUP_STORAGE_USAGE view.

Access control privileges

The following table lists privileges and the object type on which the privilege is granted for managing and using backups.

Privilege

Object type

Description

CREATE BACKUP POLICY

Schema

Grants the ability to create a backup policy in a schema. The role granting this privilege must also have the USAGE privilege on the schema.

CREATE BACKUP SET

Schema

Grants the ability to create a backup set in a schema. The role granting this privilege must also have the USAGE privilege on the schema. To actually create the backup set also requires the appropriate privilege on the object that’s the subject of the backup set: SELECT for a table backup, or USAGE for a schema backup or database backup.

APPLY

Backup policy

Grants the ability to apply a specific backup policy. Only a user with the ACCOUNTADMIN role can grant this privilege.

APPLY BACKUP RETENTION LOCK

Account

Grants the ability to create and apply backup policies with retention lock. This privilege is granted to the ACCOUNTADMIN role and can be delegated.

This privilege is required to enable a role to do the following:

  • Create a backup policy with retention lock.

  • Apply a backup policy with retention lock on a backup set.

  • Create a backup, either manually by a user or automatically on a schedule, in a backup set protected by a policy with retention lock.

APPLY LEGAL HOLD

Account

Grants the ability to add or remove a legal hold from a backup. By default, the ACCOUNTADMIN role has this privilege.

The following privilege requirements apply when Snowflake automatically creates or expires backups in the background. The owner of the backup set needs to have the following privileges:

  • The appropriate privilege on the object that’s the subject of the backup set: SELECT for a table backup, or USAGE for a schema backup or database backup.

  • Any privilege on the parent schema or database for the subject of the backup set.

  • Any privilege on the parent schema and database of the backup set.

If any of those privileges are missing, the automatic backup creation or expiration fails. You can monitor these background operations using the ACCOUNT_USAGE.BACKUP_OPERATION_HISTORY view.

Grant privileges required to create backup policies and sets

Note

  • The role used to grant these privileges must have the OWNERSHIP privilege on the schema, or it must have the CREATE BACKUP SET or CREATE BACKUP POLICY privilege WITH GRANT OPTION.

  • You can grant the following privileges to a custom account role or a database role.

To enable the role myrole to create a backup policy in schema myschema, execute the following statement:

GRANT CREATE BACKUP POLICY ON SCHEMA policy_schema TO ROLE myrole;
Copy

To enable the role myrole to create a backup set in schema myschema, execute the following statement:

GRANT CREATE BACKUP SET ON SCHEMA policy_schema TO ROLE myrole;
Copy

Grant the APPLY privilege on a backup policy to a role

Note

  • Only a user with the ACCOUNTADMIN role can grant this privilege.

  • You can grant this privilege to a custom account role or a database role.

To enable the role myrole to apply the backup policy hourly_backup_policy to a backup set, execute the following statement:

GRANT APPLY ON BACKUP POLICY hourly_backup_policy TO ROLE myrole;
Copy

Grant the APPLY BACKUP RETENTION LOCK privilege to a role

You can grant a role the privilege to apply backup policies with retention lock on backup sets.

Only a user with the ACCOUNTADMIN role can grant this privilege.

Important

Applying a backup policy with a retention lock to a backup set is irreversible. Due to the strong guarantees needed for regulatory compliance, once you put a retention lock on a backup set, you can’t revoke the lock. Snowflake support also can’t revoke such a retention lock. Backups created with a retention lock can’t be deleted until the expiration period ends.

If a Snowflake organization is deleted, the organization is no longer a Snowflake customer. In this case, Snowflake deletes all backups, including those with retention locks.

To enable the role retention_lock_admin_role to apply a backup policy with retention lock on a backup set, execute the following statement:

GRANT APPLY BACKUP RETENTION LOCK ON ACCOUNT TO ROLE retention_lock_admin_role;
Copy

Create and configure backups

This section provides example workflows for creating and restoring backups.

  1. Create a backup policy named hourly_backup_policy. Backups taken with this policy are created hourly and each backup expires after 90 days.

    CREATE BACKUP POLICY hourly_backup_policy
      SCHEDULE = '60 MINUTE'
      EXPIRE_AFTER_DAYS = 90
      COMMENT = 'Hourly backups expire after 90 days';
    
    Copy
  2. Create a backup set for table t1 with the backup policy hourly_backup_policy:

    CREATE BACKUP SET t1_backups
      FOR TABLE t1
      WITH BACKUP POLICY hourly_backup_policy;
    
    Copy
  3. Create a backup set for schema s1 with the backup policy hourly_backup_policy:

    CREATE BACKUP SET s1_backups
      FOR SCHEMA s1
      WITH BACKUP POLICY hourly_backup_policy;
    
    Copy
  4. Create a backup set for database d1 with the backup policy hourly_backup_policy:

    CREATE BACKUP SET d1_backups
      FOR DATABASE d1
      WITH BACKUP POLICY hourly_backup_policy;
    
    Copy

Create scheduled backups with retention lock

Create a backup set that automatically creates backups with a retention lock on a schedule. The retention lock prevents anyone, even privileged users, from deleting or modifying backups in any backup set that the policy is attached to.

Only a role that has the APPLY BACKUP RETENTION LOCK privilege on the account can create a backup policy with a retention lock.

Important

Applying a backup policy with a retention lock to a backup set is irreversible. Due to the strong guarantees needed for regulatory compliance, once you put a retention lock on a backup set, you can’t revoke the lock. Snowflake support also can’t revoke such a retention lock. Backups created with a retention lock can’t be deleted until the expiration period ends.

If a Snowflake organization is deleted, the organization is no longer a Snowflake customer. In this case, Snowflake deletes all backups, including those with retention locks.

  1. Create a policy with a retention lock that creates a daily backup with an expiration period of 90 days:

    CREATE BACKUP POLICY daily_backup_policy_with_lock
      WITH RETENTION LOCK
      SCHEDULE = '1440 MINUTE'
      EXPIRE_AFTER_DAYS = 90
      COMMENT = 'regulatory backups: they have a retention lock and expire after 90 days';
    
    Copy
  2. Create a backup set for table t2 with the backup policy daily_backup_policy_with_lock:

    CREATE BACKUP SET t2_backups
      FOR TABLE t2
      WITH BACKUP POLICY daily_backup_policy_with_lock;
    
    Copy
  3. Create a backup set for schema s2 with the backup policy daily_backup_policy_with_lock:

    CREATE BACKUP SET s2_backups
      FOR SCHEMA s2
      WITH BACKUP POLICY daily_backup_policy_with_lock;
    
    Copy
  4. Create a backup set for database d2 with the backup policy daily_backup_policy_with_lock:

    CREATE BACKUP SET d2_backups
      FOR DATABASE d2
      WITH BACKUP POLICY daily_backup_policy_with_lock;
    
    Copy

Create backups manually

You can manually add a backup to a backup set at any time. Doing so makes a backup of the database, schema, or table that’s associated with the backup set. You can create backups manually whether or not the backup set also has backups that are scheduled by a backup policy. If there’s a backup policy associated with the backup set, and the policy defines an expiration period, that expiration period also applies to the manual backup.

The following example creates a table backup set t1_backups and then adds the first backup to it:

CREATE BACKUP SET t1_backups FOR TABLE t1;
ALTER BACKUP SET t1_backups ADD BACKUP;
Copy

The following example creates a backup policy with hourly backups, a table backup set t2_backups that uses the policy, and then adds a manual backup to the backup set:

CREATE BACKUP POLICY hourly_backup_policy
  SCHEDULE = '60 MINUTE'
  EXPIRE_AFTER_DAYS = 7;

CREATE BACKUP SET t2_backups FOR TABLE t2 WITH BACKUP POLICY hourly_backup_policy;
-- Wait several hours. Then the backup set already contains several scheduled backups.
-- You can manually add a backup at any time, in addition to the scheduled backups.
ALTER BACKUP SET t2_backups ADD BACKUP;
Copy

You can run similar commands to add a backup to a schema or database backup set. Substitute the name of the schema or database backup set in the ALTER BACKUP SET command.

Suspend a backup policy on a backup set

When you suspend a backup policy on a backup set, you prevent the backup policy from being used to create new scheduled backups in that backup set. You also suspend the expiration of existing backups in that backup set that use the backup policy. Other backup sets that use the same policy aren’t affected.

The following example suspends a backup policy on the backup set t2_backups:

ALTER BACKUP SET t2_backups SUSPEND BACKUP POLICY;
Copy

You can also selectively suspend just the creation or just the expiration processes of the backup set. The following example suspends the creation of new backups in the backup set t3_backups, and suspends expiration of old backups from the backup set t4_backups:

ALTER BACKUP SET t3_backups SUSPEND BACKUP CREATION POLICY;
ALTER BACKUP SET t4_backups SUSPEND BACKUP EXPIRATION POLICY;
Copy

For more information about the ALTER BACKUP SET command, see ALTER BACKUP SET.

Resume a backup policy on a backup set

You can resume suspended backup policies. Doing so resumes the creation and expiration of backups according to the backup policy. If any backups reached their expiration time while the policy was suspended, Snowflake deletes those backups as soon as the policy is resumed.

The following example resumes a backup policy on the backup set t1_backup:

ALTER BACKUP SET t1_backups
  RESUME BACKUP POLICY;
Copy

You can also selectively resume just the creation or just the expiration processes of the backup set. The following example resumes the creation of new backups in the backup set t3_backups, and resumes expiration of old backups from the backup set t4_backups:

ALTER BACKUP SET t3_backups SUSPEND BACKUP CREATION POLICY;
ALTER BACKUP SET t4_backups SUSPEND BACKUP EXPIRATION POLICY;
Copy

For more information about the ALTER BACKUP SET command, see ALTER BACKUP SET.

Restore a backup

You can restore an object from a backup set by using the ID of the specific backup. For example, to restore table t1 from backup set t1_backups in the current schema, execute the following statements:

  1. Find the ID of the table backup to restore in the backup_id column:

    SHOW BACKUPS IN BACKUP SET t1_backups ->> SELECT "created_on", "backup_id", "expire_on" FROM $1;
    
    Copy
    +-------------------------------+--------------------------------------+-------------------------------+
    | created_on                    | backup_id                            | expire_on                     |
    |-------------------------------+------------------------------------------+---------------------------|
    | 2024-08-19 17:12:28.991 -0700 | 983e0b66-91eb-41cb-8a0b-037abfec1914 | 2024-08-20 17:12:28.991 -0700 |
    | 2024-08-19 18:12:33.824 -0700 | b5624ef0-1f35-452f-b132-09d8f0592e52 | 2024-08-20 18:12:33.824 -0700 |
    | 2024-08-19 19:12:43.830 -0700 | eca1a94a-fd40-46db-a2bc-4afba6a38c0a | 2024-08-20 19:12:43.830 -0700 |
    | 2024-08-19 20:12:45.446 -0700 | 8ee2fd7e-1afe-42e1-acd7-79582765a910 | 2024-08-20 20:12:45.446 -0700 |
    | 2024-08-19 21:12:55.305 -0700 | d38caf14-f8a5-4ba8-a248-8287e0cdcf40 | 2024-08-20 21:12:55.305 -0700 |
    +-------------------------------+--------------------------------------+-----------+-------------------+
    
  2. Find the ID of the schema backup to restore in the backup_id column:

    SHOW BACKUPS IN BACKUP SET s1_backups;
    
    Copy
    +-------------------------------+--------------------------------------+-------------------------------+
    | created_on                    | backup_id                            | expire_on                     |
    |-------------------------------+--------------------------------------+-------------------------------|
    | 2024-08-19 17:12:28.991 -0700 | 0a0382e1-d265-46e9-b152-4c3b2b859e65 | 2024-08-20 17:12:28.991 -0700 |
    | 2024-08-19 18:12:33.824 -0700 | 8dbcf919-3393-4590-928f-5481d7f2502f | 2024-08-20 18:12:33.824 -0700 |
    | 2024-08-19 19:12:43.830 -0700 | 8ee2fd7e-1afe-42e1-acd7-79582765a910 | 2024-08-20 19:12:43.830 -0700 |
    | 2024-08-19 20:12:45.446 -0700 | bd729a79-01bc-444d-a550-adaaa31ab62f | 2024-08-20 20:12:45.446 -0700 |
    | 2024-08-19 21:12:55.305 -0700 | 9a8802c5-5fbd-4200-a09d-43e046103939 | 2024-08-20 21:12:55.305 -0700 |
    +-------------------------------+--------------------------------------+-------------------------------+
    
  3. Find the ID of the database backup to restore in the backup_id column:

    SHOW BACKUPS IN BACKUP SET d1_backups;
    
    Copy
    +-------------------------------+--------------------------------------+-------------------------------+
    | created_on                    | backup_id                            | expire_on                     |
    |-------------------------------+--------------------------------------+-------------------------------|
    | 2024-08-19 17:12:28.991 -0700 | 42435925-4e77-4b01-ba89-8163ac03e12f | 2024-08-20 17:12:28.991 -0700 |
    | 2024-08-19 18:12:33.824 -0700 | 29c2c1b9-6599-4f0b-87b8-d43377fd7c77 | 2024-08-20 18:12:33.824 -0700 |
    | 2024-08-19 19:12:43.830 -0700 | a4283984-a063-4415-acc4-0e3c19259fad | 2024-08-20 19:12:43.830 -0700 |
    | 2024-08-19 20:12:45.446 -0700 | ffe25397-64b9-4c5f-b061-23a1885dc2dc | 2024-08-20 20:12:45.446 -0700 |
    | 2024-08-19 21:12:55.305 -0700 | 28e12b8a-aab8-40a8-ae39-9a5a5f654d66 | 2024-08-20 21:12:55.305 -0700 |
    +-------------------------------+--------------------------------------+-------------------------------+
    
  4. Restore the backup for table t1 taken on 2024-08-19 18:12:33:

    CREATE TABLE restored_t1 FROM BACKUP SET t1_backups IDENTIFIER 'b5624ef0-1f35-452f-b132-09d8f0592e52';
    
    Copy
  5. Restore the backup for schema s1 taken on 2024-08-19 18:12:33:

    CREATE SCHEMA restored_s1 FROM BACKUP SET s1_backups IDENTIFIER '8dbcf919-3393-4590-928f-5481d7f2502f';
    
    Copy
  6. Restore the backup for database d1 taken on 2024-08-19 18:12:33:

    CREATE DATABASE restored_d1 FROM BACKUP SET d1_backups IDENTIFIER '29c2c1b9-6599-4f0b-87b8-d43377fd7c77';
    
    Copy

Delete a backup from a backup set

For any backup set, you can only delete the oldest backup that doesn’t have a legal hold. You do so by specifying the backup ID. You can find the backups that don’t have a legal hold by examining the is_under_legal_hold property. You can find the oldest backup by examining the created_on property.

Note

You can’t delete any backup from a backup set if a backup policy with retention lock is attached to that backup set, or if that particular backup has a legal hold applied.

The backup that you delete from the backup set must be the earliest backup in the set.

  1. Find the ID of the table backup to delete in the backup_id column in the following output. Sorting in ascending order by the created_on column puts the oldest backup first. You could add LIMIT 1 to the SELECT command to return only the row with the details of the oldest backup.

    SHOW BACKUPS IN BACKUP SET t1_backups ->>
      SELECT "created_on", "backup_id", "expire_on" FROM $1
        WHERE "is_under_legal_hold" = 'N'
        ORDER BY "created_on";
    
    Copy
    +-------------------------------+--------------------------------------+-------------------------------+
    | created_on                    | backup_id                            | expire_on                     |
    |-------------------------------+--------------------------------------+-------------------------------|
    | 2024-08-19 17:12:28.991 -0700 | 983e0b66-91eb-41cb-8a0b-037abfec1914 | 2024-08-20 17:12:28.991 -0700 |
    | 2024-08-19 18:12:33.824 -0700 | b5624ef0-1f35-452f-b132-09d8f0592e52 | 2024-08-20 18:12:33.824 -0700 |
    | 2024-08-19 19:12:43.830 -0700 | eca1a94a-fd40-46db-a2bc-4afba6a38c0a | 2024-08-20 19:12:43.830 -0700 |
    | 2024-08-19 20:12:45.446 -0700 | 8ee2fd7e-1afe-42e1-acd7-79582765a910 | 2024-08-20 20:12:45.446 -0700 |
    | 2024-08-19 21:12:55.305 -0700 | d38caf14-f8a5-4ba8-a248-8287e0cdcf40 | 2024-08-20 21:12:55.305 -0700 |
    +-------------------------------+--------------------------------------+-------------------------------+
    
  2. Delete the t1_backups backup created on 2024-08-19 17:12:28 using the backup_id:

    ALTER BACKUP SET t1_backups DELETE BACKUP IDENTIFIER '983e0b66-91eb-41cb-8a0b-037abfec1914';
    
    Copy
  3. Find the ID of the schema backup to delete in the backup_id column in the following output:

    SHOW BACKUPS IN BACKUP SET s1_backups ->>
      SELECT "created_on", "backup_id", "expire_on" FROM $1 ORDER BY "created_on";
    
    Copy
    +-------------------------------+--------------------------------------+-------------------------------+
    | created_on                    | backup_id                            | expire_on                     |
    |-------------------------------+--------------------------------------+-------------------------------|
    | 2024-08-19 17:12:28.991 -0700 | 28e12b8a-aab8-40a8-ae39-9a5a5f654d66 | 2024-08-20 17:12:28.991 -0700 |
    | 2024-08-19 18:12:33.824 -0700 | 46a1e22a-8557-432f-a14c-1261a4ca2b34 | 2024-08-20 18:12:33.824 -0700 |
    | 2024-08-19 19:12:43.830 -0700 | 3e42fef6-b895-4055-a59f-179744d015d3 | 2024-08-20 19:12:43.830 -0700 |
    | 2024-08-19 20:12:45.446 -0700 | 7807d24e-285e-4741-b332-87c32bad5cb6 | 2024-08-20 20:12:45.446 -0700 |
    | 2024-08-19 21:12:55.305 -0700 | e022e619-ee83-45a0-b2b7-9007e284bdb3 | 2024-08-20 21:12:55.305 -0700 |
    +-------------------------------+--------------------------------------+-------------------------------+
    
  4. Delete the s1_backups backup created on 2024-08-19 17:12:28 using the backup_id:

    ALTER BACKUP SET s1_backups DELETE BACKUP IDENTIFIER '28e12b8a-aab8-40a8-ae39-9a5a5f654d66';
    
    Copy
  5. Find the ID of the database backup to delete in the backup_id column in the following output:

    SHOW BACKUPS IN BACKUP SET d1_backups ->>
      SELECT "created_on", "backup_id", "expire_on" FROM $1 ORDER BY "created_on";
    
    Copy
    +-------------------------------+--------------------------------------+-------------------------------+
    | created_on                    | backup_id                            | expire_on                     |
    |-------------------------------+--------------------------------------+-------------------------------|
    | 2024-08-19 17:12:28.991 -0700 | d3a77432-c98d-4969-91a9-fffae5dd655c | 2024-08-20 17:12:28.991 -0700 |
    | 2024-08-19 18:12:33.824 -0700 | 0a0382e1-d265-46e9-b152-4c3b2b859e65 | 2024-08-20 18:12:33.824 -0700 |
    | 2024-08-19 19:12:43.830 -0700 | 25e01ee0-ea9d-4bb7-af7f-f3fe87f9409e | 2024-08-20 19:12:43.830 -0700 |
    | 2024-08-19 20:12:45.446 -0700 | a12294f5-fc63-49cf-84f1-c7b72f7664af | 2024-08-20 20:12:45.446 -0700 |
    | 2024-08-19 21:12:55.305 -0700 | 28e12b8a-aab8-40a8-ae39-9a5a5f654d66 | 2024-08-20 21:12:55.305 -0700 |
    +-------------------------------+--------------------------------------+-------------------------------+
    
  6. Delete the d1_backups backup created on 2024-08-19 17:12:28 using the backup_id:

    ALTER BACKUP SET d1_backups DELETE BACKUP IDENTIFIER 'd3a77432-c98d-4969-91a9-fffae5dd655c';
    
    Copy
  7. Attempt to delete a more recent d1_backups backup created on 2024-08-19 21:12:55. Notice how Snowflake prevents you from deleting a backup other than the oldest one in the backup set.

    ALTER BACKUP SET d1_backups DELETE BACKUP IDENTIFIER '28e12b8a-aab8-40a8-ae39-9a5a5f654d66';
    
    Copy
    Backup '28e12b8a-aab8-40a8-ae39-9a5a5f654d66' cannot be deleted as it is not the oldest active backup in the backup set D1_BACKUPS.
    

Delete a backup set

You can delete a backup set using the DROP BACKUP SET command.

Note

You can’t delete a backup set that has a retention lock and contains unexpired backups. You also can’t delete a backup set if any of its backups has a legal hold.

Delete the t1_backups backup set:

DROP BACKUP SET t1_backups;
Copy

Delete the s1_backups backup set:

DROP BACKUP SET s1_backups;
Copy

Delete the d1_backups backup set:

DROP BACKUP SET d1_backups;
Copy

Find all the backup sets that contain backups of a specific table

The following example shows how to find all the backup sets that contain a specific table inside a specific schema and database. The SHOW TABLES command uses a pipe operator to retrieve the names of the database, schema, and table and store them in variables. The SHOW BACKUP SETS output is filtered to show the backup sets that back up the database containing the table, or the schema containing the table, or that contain that single table.

The filtered output from SHOW BACKUP SETS shows that there are two database backup sets for the database my_big_important_database, one schema backup set for the schema my_big_important_database.public, and one table backup set for the table my_big_important_database.public.my_small_secondary_table.

SHOW TABLES IN SCHEMA public ->>
  SET (dname, sname, tname) =
    (SELECT "database_name", "schema_name", "name" FROM $1
      WHERE "name" = 'MY_SMALL_SECONDARY_TABLE' AND "kind" = 'TABLE');

SHOW BACKUP SETS ->> SELECT "object_kind", "name", "database_name", "schema_name", "object_name" FROM $1
  WHERE ("object_kind" = 'TABLE' AND "database_name" = $dname AND "schema_name" = $sname AND "object_name" = $tname)
    OR ("object_kind" = 'SCHEMA' AND "database_name" = $dname AND "object_name" = $sname)
    OR ("object_kind" = 'DATABASE' AND "object_name" = $dname);
Copy
+-------------+------------------+---------------------------+-------------+---------------------------+
| object_kind | name             | database_name             | schema_name | object_name               |
|-------------+------------------+---------------------------+-------------+---------------------------|
| DATABASE    | DATABASE_BACKUP  | MY_BIG_IMPORTANT_DATABASE | PUBLIC      | MY_BIG_IMPORTANT_DATABASE |
| DATABASE    | DATABASE_BACKUP2 | MY_BIG_IMPORTANT_DATABASE | PUBLIC      | MY_BIG_IMPORTANT_DATABASE |
| SCHEMA      | SCHEMA_BACKUP3   | MY_BIG_IMPORTANT_DATABASE | PUBLIC      | PUBLIC                    |
| TABLE       | TABLE_BACKUP2    | MY_BIG_IMPORTANT_DATABASE | PUBLIC      | MY_SMALL_SECONDARY_TABLE  |
+-------------+------------------+---------------------------+-------------+---------------------------+

Create a backup for a table with dependencies

The following examples show how you might create a table backup for a table that refers to a sequence and a foreign key in a different schema. To prepare, we create the schema other_schema containing a sequence and a table. Then we create the main table in the public schema, referring to the sequence and the other table.

USE DATABASE my_big_important_database;

CREATE SCHEMA other_schema;
USE SCHEMA other_schema;

CREATE SEQUENCE my_sequence;
CREATE TABLE my_dimension_table (id INT AUTOINCREMENT PRIMARY KEY);

USE SCHEMA public;
CREATE TABLE dependent_table
(
   id INT DEFAULT my_big_important_database.other_schema.my_sequence.NEXTVAL PRIMARY KEY,
   foreign_id INT,
   FOREIGN KEY (foreign_id) REFERENCES my_big_important_database.other_schema.my_dimension_table(id)
 );

SELECT GET_DDL('TABLE','dependent_table');
Copy

The GET_DDL() output shows the references that point to the other schema:

+-------------------------------------------+
| GET_DDL('TABLE','DEPENDENT_TABLE')        |
|-------------------------------------------|
| create or replace TABLE DEPENDENT_TABLE ( |
|     ID NUMBER(38,0) NOT NULL DEFAULT MY_BIG_IMPORTANT_DATABASE.OTHER_SCHEMA.MY_SEQUENCE.NEXTVAL,
|     FOREIGN_ID NUMBER(38,0),                |
|     primary key (ID),                       |
|     foreign key (FOREIGN_ID) references MY_BIG_IMPORTANT_DATABASE.OTHER_SCHEMA.MY_DIMENSION_TABLE(ID)
| );                                        |
+-------------------------------------------+

Next, we create the backup set for the table and add a backup to it:

CREATE BACKUP SET dependency_experiments FOR TABLE dependent_table;
ALTER BACKUP SET dependency_experiments ADD BACKUP;
SHOW BACKUPS IN BACKUP SET dependency_experiments;
Copy

The SHOW BACKUPS output contains the backup_id value to use for the restore operation:

+-------------------------------+--------------------------------------+------------------------+---------------------------+--------------+-----------+
| created_on                    | backup_id                            | backup_set_name        | database_name             | schema_name  | expire_on |
|-------------------------------+--------------------------------------+------------------------+---------------------------+--------------+-----------|
| 2025-07-01 11:53:27.860 -0700 | 0fd44138-b571-449b-be0a-72779501f80e | DEPENDENCY_EXPERIMENTS | MY_BIG_IMPORTANT_DATABASE | OTHER_SCHEMA | NULL      |
+-------------------------------+--------------------------------------+------------------------+---------------------------+--------------+-----------+

We restore that table under a new name, and confirm that the restored table refers to the objects in the other schema:

CREATE TABLE restored_dependent_table FROM BACKUP SET dependency_experiments
  IDENTIFIER '0fd44138-b571-449b-be0a-72779501f80e';

SELECT GET_DDL('TABLE','restored_dependent_table');
Copy
+----------------------------------------------------+
| GET_DDL('TABLE','RESTORED_DEPENDENT_TABLE')        |
|----------------------------------------------------|
| create or replace TABLE RESTORED_DEPENDENT_TABLE ( |
|     ID NUMBER(38,0) NOT NULL DEFAULT MY_BIG_IMPORTANT_DATABASE.OTHER_SCHEMA.MY_SEQUENCE.NEXTVAL,
|     FOREIGN_ID NUMBER(38,0),                         |
|     foreign key (FOREIGN_ID) references MY_BIG_IMPORTANT_DATABASE.OTHER_SCHEMA.MY_DIMENSION_TABLE(ID),
|     primary key (ID)                                 |
| );                                                 |
+----------------------------------------------------+

To illustrate what happens if the referred-to object no longer exists, we drop the sequence and then restore the table again from the same backup:

DROP SEQUENCE my_big_important_database.other_schema.my_sequence;
CREATE TABLE OR REPLACE restored_dependent_table FROM BACKUP SET dependency_experiments
  IDENTIFIER '0fd44138-b571-449b-be0a-72779501f80e';

SELECT * FROM restored_dependent_table;
Copy

Querying the table still works:

+----+------------+
| ID | FOREIGN_ID |
|----+------------|
+----+------------+
0 Row(s) produced. Time Elapsed: 0.129s

However, operations such as GET_DDL(), DESCRIBE, and INSERT all fail because they depend on a sequence that no longer exists:

SELECT GET_DDL('TABLE','restored_dependent_table');
Copy
002073 (02000): SQL compilation error:
Sequence used as a default value in table 'MY_BIG_IMPORTANT_DATABASE.OTHER_SCHEMA.RESTORED_DEPENDENT_TABLE'
  column 'ID' was not found or could not be accessed.
DESC TABLE restored_dependent_table;
Copy
+------------+--------------+--------+-------+----------------------------------------+-------------+------------+-------+------------+---------+-------------+----------------+
| name       | type         | kind   | null? | default                                | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------------+--------------+--------+-------+----------------------------------------+-------------+------------+-------+------------+---------+-------------+----------------|
| ID         | NUMBER(38,0) | COLUMN | N     | [sequence cannot be found or accessed] | Y           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
| FOREIGN_ID | NUMBER(38,0) | COLUMN | Y     | NULL                                   | N           | N          | NULL  | NULL       | NULL    | NULL        | NULL           |
+------------+--------------+--------+-------+----------------------------------------+-------------+------------+-------+------------+---------+-------------+----------------+
INSERT INTO restored_dependent_table (foreign_id) VALUES (2);
Copy
002073 (02000): SQL compilation error:
Sequence used as a default value in table 'MY_BIG_IMPORTANT_DATABASE.OTHER_SCHEMA.RESTORED_DEPENDENT_TABLE'
  column 'ID' was not found or could not be accessed.

Create a backup for a dynamic table

A dynamic table always involves a reference to some other table. For that reason, you might prefer to use schema backups or database backups for dynamic tables, so that the original table and the dynamic table can be included in the same backup.

If you make a table backup for a dynamic table, you include the keyword DYNAMIC in the CREATE BACKUP SET command, and in the CREATE TABLE command when you restore from a backup. The following example sets up the dynamic table, a table backup set for that table, and creates the first backup:

CREATE DYNAMIC TABLE my_dynamic_table
  TARGET_LAG = '1 minute'
  WAREHOUSE = my_wh
  AS SELECT * FROM my_base_table WHERE col1 IS NOT NULL;

CREATE BACKUP SET dynamic_table_backups
  FOR DYNAMIC TABLE my_dynamic_table;

ALTER BACKUP SET dynamic_table_backups ADD BACKUP;
Copy

The following example shows how to determine the backup IDs for backups created at various times. In this case, the newest backup is the first row in the result set. Then you use the ID of the backup in the CREATE DYNAMIC TABLE command.

SHOW BACKUPS IN BACKUP SET dynamic_table_backups
  ->> SELECT "created_on", "backup_id" FROM $1
        ORDER BY "created_on" DESC;

CREATE DYNAMIC TABLE restored_dynamic_table
  FROM BACKUP SET dynamic_table_backups
    IDENTIFIER '<backup_id_from_SHOW_BACKUPS_output>';
Copy

Tip

When you restore a dynamic table from a backup, Snowflake automatically initializes the new table during its first refresh.

Monitor backups and backup operations

You can determine which backup-related objects exist, their properties, and how much storage they use by querying the following views.

Information schema:

Account usage:

Organization usage:

SQL reference topics

Backup policy

Backup set

Backups

You don’t run an actual CREATE BACKUP command. To create a new backup, you run ALTER BACKUP SET … ADD BACKUP. Or when you associate the backup set with a backup policy that has a schedule, Snowflake automatically creates backups in the backup set based on the specified schedule. To delete an older backup, you run ALTER BACKUP SET … DELETE BACKUP. Such operations require you to specify the identifier for a specific backup. You can find the backup identifiers, along with other information such as when each backup was created, by using the following command.

Restoring objects from backups

You use the syntax CREATE object_kind FROM BACKUP SET to restore each kind of object from the appropriate kind of backup set.

Further backups in the backup set use the original object, not the restored one. That’s true even if you rename the restored object to the same name as the original object. If you want to continue using the same backup set after doing a restore, you restore the object under a new name and then transfer data back to the original object.

Views

The following system views contain metadata related to backups, backup sets, and backup policies.

Information schema views

These views in the INFORMATION_SCHEMA schema contain information about backup-related objects that currently exist:

Account usage views

These views in the ACCOUNT_USAGE schema contain information at the account level about backup-related objects that exist, or have been dropped, the operations that were performed on the backups, and the storage that they use:

Organization usage views

These views in the ORGANIZATION_USAGE schema contain information at the organization level about backup-related objects that exist, or have been dropped, the operations that were performed on the backups, and the storage that they use:

Terminology change

The feature is now called backups instead of snapshots. All SQL commands, views, and privileges use BACKUP terminology:

  • CREATE BACKUP POLICY, CREATE BACKUP SET

  • ALTER BACKUP POLICY, ALTER BACKUP SET

  • DROP BACKUP POLICY, DROP BACKUP SET

  • SHOW BACKUP POLICIES, SHOW BACKUP SETS, SHOW BACKUPS IN BACKUP SET

  • BACKUPS, BACKUP_POLICIES, BACKUP_SETS views in Account Usage, Organization Usage, and Information Schema

  • APPLY BACKUP POLICY, APPLY BACKUP RETENTION LOCK privileges

The former SNAPSHOT/SNAPSHOTS names are still present but deprecated in favor of their BACKUP/BACKUPS equivalents. For example:

  • CREATE SNAPSHOT POLICY is deprecated; use CREATE BACKUP POLICY instead.

  • SNAPSHOTS view is deprecated; use BACKUPS view instead.

  • APPLY SNAPSHOT POLICY privilege is deprecated; use APPLY BACKUP POLICY privilege instead.

The deprecated commands, views, and privileges continue to work, but Snowflake intends to remove them in a future release.

Language: English