导出和导入数据

您可以使用 Cloud Firestore 托管式导出和导入服务来恢复意外删除的数据,并导出数据以供离线处理。您可以导出所有文档或仅导出特定的集合。同样,您可以导入某次导出的所有数据,或仅导入特定的集合。从一个 Cloud Firestore 数据库导出的数据可导入到另一个 Cloud Firestore 数据库中。您还可以将 Cloud Firestore 导出数据加载到 BigQuery 中

本页面介绍如何使用代管式导出和导入服务以及 Cloud Storage 来导出和导入 Cloud Firestore 文档。可通过 gcloud 命令行工具和 Cloud Firestore API (RESTRPC ) 使用 Cloud Firestore 代管式导出和导入服务。

准备工作

您必须先完成以下任务,才能使用代管式导出和导入服务:

  1. 为 Google Cloud 项目启用结算功能。只有启用了结算功能的 Google Cloud 项目才能使用导出和导入功能。
  2. Cloud Firestore 数据库位置附近为项目创建一个 Cloud Storage 存储桶。您不能使用“请求者付款”存储桶执行导出和导入操作。
  3. 确保您的账号拥有 Cloud Firestore 和 Cloud Storage 的必要权限。如果您是项目所有者,那么您的账号具有所需权限。如果不是,以下角色具有必要的导出和导入操作权限以及访问 Cloud Storage 的必要权限:

    • Cloud Firestore 角色OwnerCloud Datastore OwnerCloud Datastore Import Export Admin
    • Cloud Storage 角色OwnerStorage Admin

服务代理权限

导出和导入操作使用 Cloud Firestore 服务代理对 Cloud Storage 操作授权。Cloud Firestore 服务代理使用以下命名惯例:

Cloud Firestore 服务代理
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com

如需详细了解服务代理,请参阅服务代理

Cloud Firestore 服务代理需要能够访问导出或导入操作中使用的 Cloud Storage 存储桶。如果您的 Cloud Storage 存储桶与您的 Cloud Firestore 数据库属于同一项目,则默认情况下,Cloud Firestore 服务代理能够访问该存储桶

如果 Cloud Storage 存储桶在其他项目中,您必须向 Cloud Firestore 服务代理授予对 Cloud Storage 存储桶的访问权限。

为服务代理分配角色

您可以使用 gsutil 命令行工具分配以下角色之一。例如,如需为 Cloud Firestore 服务代理分配 Storage Admin 角色,请运行以下命令:

gsutil iam ch serviceAccount:service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com:roles/storage.admin \
    gs://[BUCKET_NAME]

PROJECT_NUMBER 替换为您的项目编号,用于为您的 Cloud Firestore 服务代理命名。如需查看服务代理名称,请参阅查看服务代理名称

或者,您可以使用 GCP 控制台分配此角色

查看服务代理名称

您可以在 Google Cloud Platform 控制台的导入/导出页面中,查看您的导入和导出操作用于对请求授权的账号。您还可以查看您的数据库使用的是 Cloud Firestore 服务代理还是旧版 App Engine 服务账号。

  1. 查看以下面的账号运行导入/导出作业标签旁边的授权账号。

对于要用于导出或导入操作的 Cloud Storage 存储桶,服务代理需要拥有 Storage Admin 角色。

为您的项目设置 gcloud

您可以通过 Google Cloud Platform 控制台或 gcloud 命令行工具启动导入和导出操作。如需使用 gcloud,请设置命令行工具并通过以下任一方式连接到您的项目:

导出数据

导出操作会将数据库中的文档复制到 Cloud Storage 存储桶中的一组文件。请注意,所导出的内容并不是导出开始那一刻截取的数据库快照,导出内容可能包括在操作过程中对数据库所做的变更。

导出所有文档

Google Cloud 控制台

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。

  3. 在导航菜单中,点击导入/导出

  4. 点击导出

  5. 点击导出整个数据库选项。

  6. 选择目标位置下,输入 Cloud Storage 存储桶的名称,或使用浏览按钮选择存储桶。

  7. 点击导出

控制台会返回到导入/导出页面。如果操作成功开始,页面会在“近期导入和导出”页面中添加一个条目。如果失败,页面会显示错误消息。

gcloud

使用 firestore export 命令导出数据库中的所有文档,注意将 [BUCKET_NAME] 替换为 Cloud Storage 存储桶的名称。添加 --async 标志可阻止 gcloud 工具等待操作完成。

  gcloud firestore export gs://[BUCKET_NAME] \
  --database=[DATABASE]

请替换以下内容:

  • BUCKET_NAME:通过在存储桶名称后面添加文件前缀来整理导出的内容,例如 BUCKET_NAME/my-exports-folder/export-name。如果您不提供文件前缀,代管式导出服务会根据当前时间戳创建一个。

  • DATABASE:要导出文档的所在的数据库的名称。对于默认数据库,请使用 --database='(default)'

导出操作一旦启动就无法通过关闭终端来取消,具体请参阅取消操作

导出特定集合

Google Cloud 控制台

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。

  3. 在导航菜单中,点击导入/导出

  4. 点击导出

  5. 点击导出一个或多个集合组选项。使用下拉菜单选择一个或多个集合组。

  6. 选择目标位置下,输入 Cloud Storage 存储桶的名称,或使用浏览按钮选择存储桶。

  7. 点击导出

控制台会返回到导入/导出页面。如果操作成功开始,页面会在“近期导入和导出”页面中添加一个条目。如果失败,页面会显示错误消息。

gcloud

如需导出特定集合组,请使用 --collection-ids 标志。该操作仅导出具有指定集合 ID 的集合组。集合组包含任意路径中具有指定集合 ID 的所有集合和子集合。

gcloud firestore export gs://[BUCKET_NAME] \
--collection-ids=[COLLECTION_ID_1],[COLLECTION_ID_2],[SUBCOLLECTION_ID_1] \
--database=[DATABASE]

例如,您可以在 foo 数据库中设计一个 restaurants 集合以包括多个子集合,例如 ratingsreviewsoutlets。若要导出集合 restaurants 及子集合 reviews,您的命令应如下所示:

gcloud firestore export gs://[BUCKET_NAME] \
--collection-ids=restaurants,reviews \
--database='cymbal'

从 PITR 时间戳导出

您可以使用 gcloud firestore export 命令将数据库从 PITR 数据导出到 Cloud Storage。您可以导出 PITR 数据,其中时间戳为过去七天内的整分钟时间戳,但不早于 earliestVersionTime。如果指定的时间戳已不存在数据,导出操作将失败。

PITR 导出操作支持所有过滤条件,包括导出所有文档和导出特定集合。

  1. 导出数据库,将 snapshot-time 参数指定为所需恢复时间戳。

    gcloud

    运行以下命令,将数据库导出到存储桶。

    gcloud firestore export gs://[BUCKET_NAME_PATH] \
        --snapshot-time=[PITR_TIMESTAMP] \
        --collection-ids=[COLLECTION_IDS] \
        --namespace-ids=[NAMESPACE_IDS]
    

    其中:

    • PITR_TIMESTAMP - 分钟粒度的 PITR 时间戳,例如 2023-05-26T10:20:00.00Z

    在导出 PITR 数据之前,请注意以下几点:

    • RFC 3339 格式指定时间戳。例如 2020-09-01T23:59:30.234233Z
    • 请确保您指定的时间戳是过去七天内的整分钟时间戳,但不早于 earliestVersionTime。如果指定的时间戳已不存在数据,则会生成错误。
    • 您无需为失败的 PITR 导出付费。

导入数据

文件导出到 Cloud Storage 中后,您可以将这些文件中的文档重新导入原项目或其他项目。请注意以下几点关于导入操作的事项:

  • 在您导入数据时,系统将使用数据库当前的索引定义来更新所需的索引。导出的数据不包含索引定义。

  • 导入操作不分配新的文档 ID,而是使用导出时捕获的 ID。在导入文档时,系统会保留其 ID 以防止 ID 冲突。如果已存在具有相同 ID 的文档,导入操作将覆盖现有文档。

  • 如果数据库中的现有文档未受到导入的影响,导入操作后该文档仍会保留在您的数据库中。

  • 导入操作不会触发 Cloud Functions。快照监听器会接收与导入操作相关的更新。

  • .overall_export_metadata 文件名必须与其父文件夹的名称一致:

    gs://BUCKET_NAME/OPTIONAL_NAMESPACE_PATH/PARENT_FOLDER_NAME/PARENT_FOLDER_NAME.overall_export_metadata

    如果移动或复制导出的输出文件,请保持 PARENT_FOLDER_NAME.overall_export_metadata 文件名不变。

导入某次导出的所有文档

Google Cloud 控制台

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。

  3. 在导航菜单中,点击导入/导出

  4. 点击导入

  5. 文件名字段中,输入已完成的导出操作中的 .overall_export_metadata 文件的文件名。您可以使用浏览按钮来帮助选择文件。

  6. 点击导入

控制台会返回到导入/导出页面。如果操作成功开始,页面会在“近期导入和导出”页面中添加一个条目。如果失败,页面会显示错误消息。

gcloud

使用 firestore import 命令导入先前导出操作中的文档。

gcloud firestore import gs://[BUCKET_NAME]/[EXPORT_PREFIX]/ --database=[DATABASE]

请替换以下内容:

  • BUCKET_NAME/EXPORT_PREFIX:导出文件的位置。

  • DATABASE:数据库的名称。对于默认数据库,请使用 --database='(default)'

例如:

gcloud firestore import gs://my-bucket/2017-05-25T23:54:39_76544/ --database='cymbal'

您可以在 Google Cloud Platform 控制台的 Cloud Storage 浏览器中确认导出文件的位置:

打开 Cloud Storage 浏览器

导入操作一旦启动就无法通过关闭终端来取消,具体请参阅取消操作

导入特定集合

Google Cloud 控制台

您无法在控制台中选择特定的集合。请改用 gcloud

gcloud

如需从一组导出文件中导入特定的集合组,请使用 --collection-ids 标志。该操作仅导入具有指定集合 ID 的集合组。 集合组包含任意路径中具有指定集合 ID 的所有集合和子集合。使用 --database 标志指定数据库名称。对于默认数据库,请使用 --database='(default)'

只有包含特定集合组的导出文件支持导入特定集合组。您无法从包含所有文档的导出文件中导入特定的集合。

  gcloud firestore import gs://[BUCKET_NAME]/[EXPORT_PREFIX]/ \
  --collection-ids=[COLLECTION_ID_1],[COLLECTION_ID_2],[SUBCOLLECTION_ID_1] \
  --database=[DATABASE]

导入 PITR 导出文件

按照导入所有文档中的步骤导入您导出的数据库。如果数据库中已有任何文档,这类文档将会被覆盖。

管理导出和导入操作

在您启动导出或导入操作后,Cloud Firestore 会为操作分配唯一的名称。您可以使用操作名称来删除、取消操作或检查操作状态。

操作名称的前缀为 projects/[PROJECT_ID]/databases/(default)/operations/,例如:

projects/my-project/databases/(default)/operations/ASA1MTAwNDQxNAgadGx1YWZlZAcSeWx0aGdpbi1zYm9qLW5pbWRhEgopEg

不过,您可以在指定 describecanceldelete 命令的操作名称时省略前缀。

列出所有导出和导入操作

Google Cloud 控制台

您可以在 Google Cloud Platform 控制台的导入/导出页面中查看最近的导出和导入操作列表。

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。

  3. 在导航菜单中,点击导入/导出

gcloud

使用 operations list 命令可查看所有正在运行和最近完成的导出和导入操作:

gcloud firestore operations list

查看操作状态

Google Cloud 控制台

您可以在 Google Cloud Platform 控制台的导入/导出页面中查看最近的导出或导入操作的状态。

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。

  3. 在导航菜单中,点击导入/导出

gcloud

使用 operations describe 命令可显示导出或导入操作的状态。

gcloud firestore operations describe [OPERATION_NAME]

预估完成时间

用于获取运行时间较长的操作状态的请求会返回指标 workEstimatedworkCompleted。返回的这两个指标均包含字节数和实体数:

  • workEstimated 表示操作将处理的预估总字节数和文档数。如果 Cloud Firestore 无法进行估算,则可能会省略该指标。

  • workCompleted 表示目前已处理的字节数和文档数。 操作完成后,该值会显示实际处理的总字节数和总文档数,可能大于 workEstimated 的值。

workCompleted 除以 workEstimated 可得出粗略的进度估算值。该估算值可能不准确,因为它所依据的是延迟的统计信息收集操作。

取消操作

Google Cloud 控制台

您可以在 Google Cloud Platform 控制台的导入/导出页面中取消正在运行的导出或导入操作。

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。

  3. 在导航菜单中,点击导入/导出

“近期导入和导出”表中,当前正在执行的操作在“已完成”列中有一个取消按钮。点击取消按钮可停止操作。按钮会变为“正在取消”消息,然后当操作完全停止时,变为“已取消”。

gcloud

使用 operations cancel 命令可停止正在进行的操作:

gcloud firestore operations cancel [OPERATION_NAME]

取消正在进行的操作并不会撤消操作。取消的导出操作会在 Cloud Storage 中留下已导出的文档,而取消的导入操作会留下已对数据库进行的更新。您无法导入部分完成的导出文件。

删除操作

使用 gcloud firestore operations delete 命令可从近期操作列表中移除操作。此命令不会从 Cloud Storage 中删除导出文件。

gcloud firestore operations delete [OPERATION_NAME]

导出和导入操作的计费与价格

在使用代管式导出和导入服务前,您需要为 Google Cloud 项目启用结算功能。

对于导出和导入操作,您需按 Cloud Firestore 价格中列出的费率支付文档读写费用。导出操作会对每个导出的文档执行一次读取操作。导入操作会对每个导入的文档执行一次写入操作。

存储在 Cloud Storage 中的输出文件计入您的 Cloud Storage 数据存储费用

导出和导入操作的费用不计入您的支出限额。导出或导入操作在完成之前不会触发 Google Cloud 预算提醒。同样,在导出或导入操作期间执行的读写会在操作完成后计入您的每日配额。导出和导入操作不会影响控制台的使用量部分中显示的使用量。

查看导出和导入费用

导出和导入操作会为收费操作添加 goog-firestoremanaged:exportimport 标签。在 Cloud Billing 报告页面中,您可以使用此标签查看与导入和导出操作相关的费用:

从过滤条件菜单访问 goog-firestoremanaged 标签。

导出到 BigQuery

您可以将 Cloud Firestore 导出文件中的数据加载到 BigQuery,但前提是您指定了 collection-ids 过滤条件。请参阅从 Cloud Firestore 导出文件中加载数据

BigQuery 列限制

BigQuery 对表格施加的列数上限为 10000。Cloud Firestore 导出操作会为每个集合组生成 BigQuery 表格架构。在此架构中,集合组中的每个唯一字段名称都会变为架构列。

如果集合组的 BigQuery 架构超过 10000 列,则 Cloud Firestore 导出操作会尝试将映射字段视为字节,从而保持在列限制以下。如果此转化使列数低于 10000,您可以将数据加载到 BigQuery 中,但无法查询映射字段中的子字段。如果列数仍然超过 10000,则导出操作不会为该集合组生成 BigQuery 架构,而且您无法将其数据加载到 BigQuery 中。

导出格式和元数据文件

代管式导出的输出使用 LevelDB 日志格式

元数据文件

导出操作将为您指定的每个集合组创建一个元数据文件。元数据文件通常命名为 ALL_NAMESPACES_KIND_[COLLECTION_GROUP_ID].export_metadata

元数据文件是协议缓冲区,您可以使用 protoc 协议编译器对其进行解码。例如,您可以对元数据文件进行解码,以确定导出文件包含的集合组:

protoc --decode_raw < export0.export_metadata

服务代理迁移

Cloud Firestore 使用 Cloud Firestore 服务代理(而不是 App Engine 服务账号)来对导入和导出操作授权。服务代理和服务账号使用以下命名惯例:

Cloud Firestore 服务代理
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com

Cloud Firestore 以前使用的是 App Engine 默认服务账号,而不是 Cloud Firestore 服务代理。如果您的数据库仍使用 App Engine 服务账号来导入或导出数据,我们建议您按照本部分中的说明迁移到使用 Cloud Firestore 服务代理。

App Engine 服务账号
PROJECT_ID@appspot.gserviceaccount.com

最好使用 Cloud Firestore 服务代理,因为它专用于 Cloud Firestore。App Engine 服务账号由多项服务共享。

查看授权账号

您可以在 Google Cloud Platform 控制台的导入/导出页面中,查看您的导入和导出操作使用哪个账号为请求授权。您还可以查看自己的数据库是否已经在使用 Cloud Firestore 服务代理。

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。
  3. 在导航菜单中,点击导入/导出

  4. 查看以下面的账号运行导入/导出作业标签旁边的授权账号。

如果您的项目不使用 Cloud Firestore 服务代理,则您可以使用以下任一方法迁移到 Cloud Firestore 服务代理:

第一种方法是首选方法,因为它会将影响范围局限到单个 Cloud Firestore 项目。第二种方法不是首选方法,因为它不会迁移现有 Cloud Storage 存储桶权限。但是,它能够在组织级层提供安全合规性。

检查和更新 Cloud Storage 存储桶权限以进行迁移

该迁移过程包含两个步骤:

  1. 更新 Cloud Storage 存储桶权限。如需了解详情,请参阅下一部分。
  2. 确认迁移到 Cloud Firestore 服务代理。

服务代理的存储桶权限

对于使用其他项目中的 Cloud Storage 存储桶的任何导出或导入操作,您必须向 Cloud Firestore 服务代理授予该存储桶的权限。例如,将数据移至其他项目的操作需要访问该项目中的存储桶。否则,这些操作会在迁移到 Cloud Firestore 服务代理后失败。

属于同一项目的导入和导出工作流不需要更改权限。默认情况下,Cloud Firestore 服务代理可以访问同一项目中的存储桶。

更新其他项目中的 Cloud Storage 存储桶的权限,以便向 service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com 服务代理授予访问权限。为该服务代理授予 Firestore Service Agent 角色。

Firestore Service Agent 角色拥有 Cloud Storage 存储桶的读写权限。如果您需要授予只读或只写权限,请使用自定义角色

下一部分中介绍的迁移过程可帮助您识别可能需要更新权限的 Cloud Storage 存储桶。

将项目迁移到 Firestore 服务代理

完成以下步骤以从 App Engine 服务账号迁移到 Cloud Firestore 服务代理。迁移完成后将无法撤消。

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。
  3. 在导航菜单中,点击导入/导出

  4. 如果您的项目尚未迁移到 Cloud Firestore 服务代理,您会看到一条描述迁移的横幅和一个检查存储桶状态按钮。下一步可帮助您识别并修复潜在的权限错误。

    点击检查存储桶状态

    此时系统将显示一个菜单,其中包含用于完成迁移的选项和 Cloud Storage 存储桶列表。该列表可能需要几分钟时间才能完成加载。

    此列表包括一些存储桶,这些存储桶最近在导入和导出操作中使用过,但目前没有为 Cloud Firestore 服务代理授予读写权限。

  5. 记下您的项目的 Cloud Firestore 服务代理的主账号名称。服务代理名称显示在要向其授予访问权限的服务代理标签下方。
  6. 对于该列表中将用于未来导入或导出操作的任何存储桶,请完成以下步骤:

    1. 在相应存储桶的表行中,点击修复。此操作会在新的标签页中打开该存储桶的权限页面。

    2. 点击添加
    3. 新的主账号字段中,输入 Cloud Firestore 服务代理的名称。
    4. 选择角色字段中,选择服务代理 > Firestore Service Agent
    5. 点击保存
    6. 返回“Cloud Firestore 导入/导出”页面所在的标签页。
    7. 对该列表中的其他存储桶重复执行上述步骤。请务必查看该列表的所有页面。
  7. 点击迁移到 Firestore Service Agent。如果仍存在权限检查失败的存储桶,则您需要点击迁移来确认迁移。

    迁移完成时,您会收到提醒。迁移操作无法撤消。

查看迁移状态

如需验证项目的迁移状态,请执行以下操作:

  1. 在 Google Cloud Platform 控制台中,进入数据库页面。

    前往“数据库”

  2. 从数据库列表中选择所需的数据库。
  3. 在导航菜单中,点击导入/导出

  4. 以下面的账号运行导入/导出作业标签旁边寻找主账号。

    如果主账号是 service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com,则表示您的项目已迁移到 Cloud Firestore 服务代理。迁移操作无法撤消。

    如果项目尚未迁移,则该页面顶部会显示一条横幅和一个检查存储桶状态按钮。请参阅迁移到 Firestore 服务代理完成迁移。

添加组织范围的政策限制条件

  • 在您的组织的政策中设置以下限制条件:

    需要 Firestore 服务代理才能导入/导出 (firestore.requireP4SAforImportExport)。

    此限制条件要求导入和导出操作使用 Cloud Firestore 服务代理为请求授权。 如需设置此限制条件,请参阅创建和管理组织政策

如果应用此组织政策限制条件,则系统不会自动为 Cloud Firestore 服务代理授予适当的 Cloud Storage 存储桶权限。

如果该限制条件对任何导入或导出工作流造成权限错误,您可以将其停用,改为使用默认服务账号。检查和更新 Cloud Storage 存储桶权限后,您可以再次启用该限制条件。