本页介绍如何使用代管式导出和导入服务来导出和导入 Datastore 模式 Firestore 实体。您可以通过 Google Cloud 控制台、Google Cloud CLI 和 Datastore Admin API(REST、RPC)使用代管式导出和导入服务。
利用代管式导出和导入服务,您可以恢复意外删除的数据,可以导出数据进行离线处理。您可以导出所有实体,或仅导出特定种类的实体。同样地,您可以从某个导出中导入所有数据,或仅导入特定种类的数据。使用托管式导出和导入服务时,请注意以下事项:
导出服务使用最终一致的读取。您不能假定导出发生在单一时间点上。导出可能包括导出开始后写入的实体,并排除导出开始前写入的实体。
导出不包含任何索引。在您导入数据时,将使用数据库当前的索引定义自动重建所需索引。每个实体的属性值索引设置会被导出,并在导入时得以保持。
导入不会向实体分配新 ID。导入使用导出时存在的 ID,并覆盖具有相同 ID 的任何现有实体。在导入过程中,正在导入的实体的 ID 将被预留。如果在导入运行过程中启用了写入,此功能可防止与新实体发生 ID 冲突。
如果数据库中的某个实体未受到导入服务的影响,则在导入完成后,该实体将保留在数据库中。
从一个 Datastore 模式数据库导出的数据可导入另一个 Datastore 模式数据库中,甚至可以导入到属于其他项目的此类数据库中。
代管式导出和导入服务将并发导出和导入数限制为 50,并且对于一个项目每分钟最多允许 20 个导出和导入请求。 对于每个请求,服务会将实体过滤条件组合的数量限制为 100。
代管式导出的输出使用 LevelDB 日志格式。
如需只导入实体的子集,或者如需将数据导入 BigQuery,您必须在导出中指定实体过滤条件。
.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 项目启用结算功能。 只有启用了结算功能的 Google Cloud 项目才能使用导出和导入功能。
在 Datastore 模式 Firestore 数据库所在的位置创建 Cloud Storage 存储分区。您不能使用“请求者付款”存储分区执行导出和导入操作。
如果要导出数据,请为您的用户账号分配一个授予
datastore.databases.export
权限的 IAM 角色;如果要导入数据,请为您的用户账号分配一个授予datastore.databases.import
权限的 IAM 角色。例如,Datastore Import Export Admin
角色可同时授予这两种权限。如果 Cloud Storage 存储桶位于其他项目中,请向 Firestore 服务代理授予对该存储桶的访问权限。
为您的项目设置 gcloud
如果您计划使用 gcloud
启动您的导入和导出操作,请设置 gcloud
并通过以下方式之一关联到您的项目:
使用 Cloud Shell 从 Google Cloud 控制台访问
gcloud
。配置 gcloud CLI 以使用当前项目:
gcloud config set project project-id
权限
如需运行导出和导入操作,您的用户账号和项目的 Datastore 模式服务代理需要具备以下 Identity and Access Management 权限。
用户账号权限
发起该操作的用户账号或服务账号需要 datastore.databases.export
和 datastore.databases.import
IAM 权限。如果您是 Project Owner,则您的账号拥有所需的权限。如果不是,以下 IAM 角色可授予必要权限:
- Datastore Owner
- Datastore Import Export Admin
您还可以使用自定义角色分配这些权限。
项目所有者可以按照授予访问权限中的步骤授予其中一个角色。
服务代理权限
导出和导入操作使用 Firestore 服务代理对 Cloud Storage 操作授权。Firestore 服务代理使用以下命名惯例:
- Firestore 服务代理
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com
如需详细了解服务代理,请参阅服务代理。
Firestore 服务代理需要能够访问导出或导入操作中使用的 Cloud Storage 存储桶。如果您的 Cloud Storage 存储桶与您的 Firestore 数据库位于同一项目中,则默认情况下,Firestore 服务代理能够访问该存储桶。
如果 Cloud Storage 存储桶在其他项目中,您必须向 Firestore 服务代理授予对 Cloud Storage 存储桶的访问权限。
为服务代理分配角色
您可以使用 gsutil 命令行工具分配以下角色之一。例如,如需为 Firestore 服务代理分配 Storage Admin 角色,请运行以下命令:
gsutil iam ch serviceAccount:service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com:roles/storage.admin \ gs://[BUCKET_NAME]
将 PROJECT_NUMBER
替换为您的项目编号,用于为您的 Firestore 服务代理命名。如需查看服务代理名称,请参阅查看服务代理名称。
或者,您也可以使用 Google Cloud 控制台分配此角色。
查看服务代理名称
您可以在 Google Cloud 控制台的导入/导出页面中,查看您的导入和导出操作用于对请求授权的账号。您还可以查看您的数据库使用的是 Firestore 服务代理还是旧版 App Engine 服务账号。
-
在 Google Cloud 控制台中,转到数据库页面。
-
从数据库列表中选择所需的数据库。
-
在导航菜单中,点击导入/导出。
- 查看以下面的账号运行导入/导出作业标签旁边的授权账号。
导出操作
对于涉及其他项目中的存储桶的导出操作,请修改存储桶的权限,将以下 Identity and Access Management 角色之一分配给您的 Datastore 模式数据库所属项目的 Datastore 模式服务代理:
- Storage Admin
- Owner(基本角色)
您还可以创建一个 IAM 自定义角色,其权限与上述角色包含的权限略有不同:
storage.buckets.get
storage.objects.create
storage.objects.delete
storage.objects.list
导入操作
对于涉及其他项目中的 Cloud Storage 存储桶的导入操作,请修改存储桶的权限,将以下 Cloud Storage 角色之一分配给您的 Datastore 模式数据库所属项目的 Datastore 模式服务代理:
- Storage Admin
- Storage Object Viewer 和 Storage Legacy Bucket Reader
您还可以创建具备以下权限的 IAM 自定义角色:
storage.buckets.get
storage.objects.get
开始执行代管式导出和导入操作
本部分介绍如何开始执行代管式导出或导入操作。
导出所有实体
控制台
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
- 在导航菜单中,点击导入/导出。
- 点击导出。
- 将命名空间字段设置为
All Namespaces
,并将种类字段设置为All Kinds
。 - 在目标下,输入您的 Cloud Storage 存储分区的名称。
- 点击导出。
控制台会返回到导入/导出页面。提醒会报告代管式导出请求是成功还是失败。
gcloud
使用 gcloud firestore export
命令可导出数据库中的所有实体。
gcloud firestore export gs://bucket-name --async --database=DATABASE
其中,bucket-name 是您的 Cloud Storage 存储分区的名称和可选前缀,例如 bucket-name/datastore-exports/export-name
。您无法为其他导出操作重复使用相同的前缀。如果您不提供文件前缀,代管式导出服务会根据当前时间创建一个。
使用 [--async
][async-flag] 标志可阻止 gcloud
等待操作完成。如果您省略 --async
标志,则可以输入 Ctrl+c
以停止等待某一操作。这不会取消该操作。
将 --database
标志设置为要从中导出实体的目标数据库的名称。对于默认数据库,请使用 --database='(default)'
。
rest
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- bucket-name:您的 Cloud Storage 存储分区名称
HTTP 方法和网址:
POST https://datastore.googleapis.com/v1/projects/project-id:export
请求 JSON 正文:
{ "outputUrlPrefix": "gs://bucket-name", }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/project-id/operations/operation-id", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata", "common": { "startTime": "2019-09-18T18:42:26.591949Z", "operationType": "EXPORT_ENTITIES", "state": "PROCESSING" }, "entityFilter": {}, "outputUrlPrefix": "gs://bucket-name/2019-09-18T18:42:26_85726" } }
导出特定种类或命名空间
如需导出种类和/或命名空间的特定子集,请提供包含种类和命名空间 ID 值的实体过滤条件。 每个请求最多只能包含 100 个实体过滤条件组合,过滤后的种类和命名空间的每个组合均作为单独的过滤条件计入此限制内。
控制台
在控制台中,您可以选择所有种类或某一特定类型。 同样,您可以选择所有命名空间或某一特定命名空间。
如需指定要导出的命名空间和种类的列表,请改用 gcloud
。
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击导入/导出。
点击导出。
将命名空间字段设置为
All Namespaces
或某一命名空间的名称。将种类字段设置为
All Kinds
或种类名称。在目标下,输入您的 Cloud Storage 存储分区的名称。
点击导出。
控制台会返回到导入/导出页面。提醒会报告代管式导出请求是成功还是失败。
gcloud
gcloud firestore export --collection-ids="KIND1,KIND2" \ --namespaces="(default),NAMESPACE2" \ gs://bucket-name \ --async \ --database=DATABASE
其中,bucket-name 是您的 Cloud Storage 存储分区的名称和可选前缀,例如 bucket-name/datastore-exports/export-name
。您无法为其他导出操作重复使用相同的前缀。如果您不提供文件前缀,代管式导出服务会根据当前时间创建一个。
使用 [--async
][async-flag] 标志可阻止 gcloud
等待操作完成。如果您省略 --async
标志,则可以输入 Ctrl+c
以停止等待某一操作。这不会取消该操作。
将 --database
标志设置为要从中导出特定种类或命名空间的数据库的名称。对于默认数据库,请使用 --database='(default)'
。
rest
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- bucket-name:您的 Cloud Storage 存储分区名称
- kind:实体种类
- namespace:命名空间 ID(对于默认命名空间 ID,使用 "")
HTTP 方法和网址:
POST https://datastore.googleapis.com/v1/projects/project-id:export
请求 JSON 正文:
{ "outputUrlPrefix": "gs://bucket-name", "entityFilter": { "kinds": ["kind"], "namespaceIds": ["namespace"], }, }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/project-id/operations/operation-id", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata", "common": { "startTime": "2019-09-18T21:17:36.232704Z", "operationType": "EXPORT_ENTITIES", "state": "PROCESSING" }, "entityFilter": { "kinds": [ "Task" ], "namespaceIds": [ "" ] }, "outputUrlPrefix": "gs://bucket-name/2019-09-18T21:17:36_82974" } }
元数据文件
导出操作会为指定的每个命名空间-种类对创建一个元数据文件。元数据文件通常命名为 NAMESPACE_NAME_KIND_NAME.export_metadata
。但是,如果某个命名空间或种类会创建出无效的 Cloud Storage 对象名称,则文件将命名为 export[NUM].export_metadata
。
元数据文件是 Protocol Buffers,可通过 protoc
协议编译器进行解码。例如,您可以对元数据文件进行解码,以确定导出文件包含的命名空间和种类:
protoc --decode_raw < export0.export_metadata
导入所有实体
控制台
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击导入/导出。
点击导入。
在
File
字段中,点击“浏览”并选择.overall_export_metadata
文件。确保
.overall_export_metadata
文件未从默认位置移出。将命名空间字段设置为
All Namespaces
,并将种类字段设置为All Kinds
。点击导入。
控制台会返回到导入/导出页面。提醒会报告代管式导入请求是成功还是失败。
gcloud
您可以使用 gcloud firestore import 命令导入之前使用代管式导出服务导出的所有实体。
gcloud firestore import gs://bucket-name/file-path/file-name.overall_export_metadata \ --async \ --database=DATABASE
其中 bucket-name/file-path/file-name 是 Cloud Storage 存储分区中 overall_export_metadata
文件的路径。
使用 [--async
][async-flag] 标志可阻止 gcloud
等待操作完成。如果您省略 --async
标志,则可以输入 Ctrl+c
以停止等待某一操作。这不会取消该操作。
将 --database
标志设置为要将所有实体导入到其中的数据库的名称。对于默认数据库,请使用 --database='(default)'
。
rest
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- bucket-name:您的 Cloud Storage 存储分区名称
- object-name:您的 Cloud Storage 对象名称(示例:
2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata
)
HTTP 方法和网址:
POST https://datastore.googleapis.com/v1/projects/project-id:import
请求 JSON 正文:
{ "inputUrl": "gs://bucket-name/object-name", }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/project-id/operations/operation-id", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ImportEntitiesMetadata", "common": { "startTime": "2019-09-18T21:25:02.863621Z", "operationType": "IMPORT_ENTITIES", "state": "PROCESSING" }, "entityFilter": {}, "inputUrl": "gs://bucket-name/2019-09-18T18:42:26_85726/2019-09-18T18:42:26_85726.overall_export_metadata" } }
找到您的 overall_export_metadata
文件
您可以使用 Google Cloud 控制台中的 Cloud Storage 浏览器确定用于导入位置的值:
您还可以列出并描述已完成的操作。outputURL
字段显示 overall_export_metadata
文件的名称:
"outputUrl": "gs://bucket-name/2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata",
导入特定种类或命名空间
如需导入种类和/或命名空间的特定子集,请提供包含种类和命名空间 ID 值的实体过滤条件。
只有在使用实体过滤条件创建了导出文件时,才能指定种类和命名空间。您无法从包含所有实体的导出文件导入种类和命名空间的子集。
控制台
在控制台中,您可以选择所有种类或某一特定类型。 同样,您可以选择所有命名空间或某一特定命名空间。
如需指定要导入的命名空间和种类的列表,请改用 gcloud
。
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击导入/导出。
点击导入。
在
File
字段中,点击“浏览”并选择.overall_export_metadata
文件。请务必导入
.overall_export_metadata
文件,而不是.export_metadata
文件。将命名空间字段设置为
All Namespaces
或某一特定命名空间。将种类字段设置为
All Kinds
或某一特定种类。点击导入。
控制台会返回到导入/导出页面。提醒会报告代管式导入请求是成功还是失败。
gcloud
gcloud firestore import --collection-ids="KIND1,KIND2" \ --namespaces="(default),NAMESPACE2" \ gs://bucket-name/file-path/file-nameoverall_export_metadata \ --async \ --database=DATABASE
其中 bucket-name/file-path/file-name 是 Cloud Storage 存储分区中 overall_export_metadata
文件的路径。
使用 [--async
][async-flag] 标志可阻止 gcloud
等待操作完成。如果您省略 --async
标志,则可以输入 Ctrl+c
以停止等待某一操作。这不会取消该操作。
将 --database
标志设置为您要导入特定种类或命名空间的数据库的名称。对于默认数据库,请使用 --database='(default)'
。
rest
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- bucket-name:您的 Cloud Storage 存储分区名称
- object-name:您的 Cloud Storage 对象名称(示例:
2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata
) - kind:实体种类
- namespace:命名空间 ID(对于默认命名空间 ID,使用 "")
HTTP 方法和网址:
POST https://datastore.googleapis.com/v1/projects/project-id:import
请求 JSON 正文:
{ "inputUrl": "gs://bucket-name/object-name", "entityFilter": { "kinds": ["kind"], "namespaceIds": ["namespace"], }, }
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/project-id/operations/operation-id", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ImportEntitiesMetadata", "common": { "startTime": "2019-09-18T21:51:02.830608Z", "operationType": "IMPORT_ENTITIES", "state": "PROCESSING" }, "entityFilter": { "kinds": [ "Task" ], "namespaceIds": [ "" ] }, "inputUrl": "gs://bucket-name/2019-09-18T21:49:25_96833/2019-09-18T21:49:25_96833.overall_export_metadata" } }
从 PITR 数据导出和导入
您可以使用 gcloud firestore export
命令将数据库从 PITR 数据导出到 Cloud Storage。您可以导出 PITR 数据,其中时间戳为过去七天内的整分钟时间戳,但不早于 earliestVersionTime
。如果指定的时间戳已不存在数据,导出操作将失败。
PITR 导出操作支持所有过滤条件,包括导出所有实体和导出特定种类或命名空间。
导出数据库,将
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
。
还支持 [使用实体过滤条件导出种类和/或命名空间的特定子集][export-kind]。
在导出 PITR 数据之前,请注意以下几点:
- 以 RFC 3339 格式指定时间戳。例如
2020-09-01T23:59:30.234233Z
。 - 请确保您指定的时间戳是过去七天内的整分钟时间戳,但不早于
earliestVersionTime
。如果指定时间戳下数据不再存在,您将收到错误消息。 - 您无需为失败的 PITR 导出付费。
导入到数据库。
按照导入所有实体中的步骤导入您导出的数据库。如果数据库中已有任何实体,这类实体将会被覆盖。还支持 [使用实体过滤条件导入种类和/或命名空间的特定子集][import-kind]。
导入转换
从另一个项目导入实体时,请注意实体键包括项目 ID。导入操作会使用目标项目的 ID 更新导入数据中的实体键和键引用属性。如果此更新增加了实体大小,则可能会导致导入操作出现“实体过大”或“索引条目过大”错误。
为避免出现这两种错误,请导入项目 ID 较短的目标项目。 这不会影响来自同一项目的数据的导入操作。
管理长时间运行的操作
代管式导入和导出操作是长时间运行的操作。 这些方法调用可能需要大量时间才能完成。
在您开始执行导出或导入操作后,Datastore 模式会为操作分配唯一名称。您可以使用操作名称来删除、取消操作或检查操作状态。
操作名称的前缀为 projects/[PROJECT_ID]/databases/(default)/operations/
,例如:
projects/project-id/databases/(default)/operations/ASA1MTAwNDQxNAgadGx1YWZlZAcSeWx0aGdpbi1zYm9qLW5pbWRhEgopEg
您可以在指定 gcloud
命命令的操作名称时省略前缀。
列出所有长时间运行的操作
您可以通过以下方式查看正在进行的操作和最近完成的操作。最近几天内完成的操作都会列出:
控制台
您可以在 Google Cloud 控制台的导入/导出页面中查看长时间运行的操作列表。
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击导入/导出。
gcloud
如需列出长时间运行的操作,请使用 gcloud datastore operations list 命令。
gcloud datastore operations list
例如,最近完成的导出操作会显示以下信息:
{ "operations": [ { "name": "projects/project-id/operations/ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata", "common": { "startTime": "2017-12-05T23:01:39.583780Z", "endTime": "2017-12-05T23:54:58.474750Z", "operationType": "EXPORT_ENTITIES" }, "progressEntities": { "workCompleted": "21933027", "workEstimated": "21898182" }, "progressBytes": { "workCompleted": "12421451292", "workEstimated": "9759724245" }, "entityFilter": { "namespaceIds": [ "" ] }, "outputUrlPrefix": "gs://bucket-name" }, "done": true, "response": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesResponse", "outputUrl": "gs://bucket-name/2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata" } } ] }
rest
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
HTTP 方法和网址:
GET https://datastore.googleapis.com/v1/projects/project-id/operations
如需发送您的请求,请展开以下选项之一:
请参阅下方有关响应的信息。
例如,最近完成的导出操作会显示以下信息:
{ "operations": [ { "name": "projects/project-id/operations/ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata", "common": { "startTime": "2017-12-05T23:01:39.583780Z", "endTime": "2017-12-05T23:54:58.474750Z", "operationType": "EXPORT_ENTITIES" }, "progressEntities": { "workCompleted": "21933027", "workEstimated": "21898182" }, "progressBytes": { "workCompleted": "12421451292", "workEstimated": "9759724245" }, "entityFilter": { "namespaceIds": [ "" ] }, "outputUrlPrefix": "gs://bucket-name" }, "done": true, "response": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesResponse", "outputUrl": "gs://bucket-name/2017-05-25T23:54:39_76544/2017-05-25T23:54:39_76544.overall_export_metadata" } } ] }
查看操作状态
如需查看长时间运行的操作的状态,请执行以下操作:
控制台
您可以在 Google Cloud 控制台的导入/导出页面中查看最近的导出和导入操作的列表。
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击导入/导出。
gcloud
使用 operations describe
命令显示长时间运行的操作的状态。
gcloud datastore operations describe operation-name
rest
在使用任何请求数据之前,请先进行以下替换:
- project-id:您的项目 ID
- operation-name:操作名称
HTTP 方法和网址:
GET https://datastore.googleapis.com/v1/projects/project-id/operations/operation-name
如需发送您的请求,请展开以下选项之一:
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/project-id/operations/ASA3ODAwMzQxNjIyChp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKLRI", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata", "common": { "startTime": "2019-10-08T20:07:28.105236Z", "endTime": "2019-10-08T20:07:36.310653Z", "operationType": "EXPORT_ENTITIES", "state": "SUCCESSFUL" }, "progressEntities": { "workCompleted": "21", "workEstimated": "21" }, "progressBytes": { "workCompleted": "2272", "workEstimated": "2065" }, "entityFilter": {}, "outputUrlPrefix": "gs://bucket-name/2019-10-08T20:07:28_28481" }, "done": true, "response": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesResponse", "outputUrl": "gs://bucket-name/2019-10-08T20:07:28_28481/2019-10-08T20:07:28_28481.overall_export_metadata" } }
估计完成时间
操作运行时,查看 state
字段的值可了解操作的总体状态。
用于获取运行时间较长的操作状态的请求会返回指标 workEstimated
和 workCompleted
。返回的这两个指标均包含字节数和实体数:
workEstimated
表示操作将处理的预估总字节数和文档数。如果 Datastore 模式无法进行估算,则可能会省略该指标。workCompleted
表示目前已处理的字节数和文档数。 操作完成后,该值会显示实际处理的总字节数和总文档数,可能大于workEstimated
的值。
将 workCompleted
除以 workEstimated
可得出粗略的进度估算值。该估算值可能不准确,因为它所依据的是延迟的统计信息收集操作。
例如,下面是一个导出操作的进度状态:
{ "operations": [ { "name": "projects/project-id/operations/ASAyMDAwOTEzBxp0bHVhZmVkBxJsYXJ0bmVjc3Utc2Jvai1uaW1kYRQKKhI", "metadata": { "@type": "type.googleapis.com/google.datastore.admin.v1.ExportEntitiesMetadata", ... "progressEntities": { "workCompleted": "1", "workEstimated": "3" }, "progressBytes": { "workCompleted": "85", "workEstimated": "257" }, ...
操作完成后,操作说明将包含 "done":
true
。查看 state
字段的值,了解操作的结果。如果没有在响应中设置 done
字段,则其值为 false
。对于进行中的操作,不要依赖 done
值是否存在。
取消操作
控制台
您可以在 Google Cloud 控制台的导入/导出页面中取消正在运行的导出或导入操作。
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击导入/导出。
在“近期导入和导出”表中,当前正在执行的操作在“已完成”列中有一个取消按钮。点击取消按钮可停止操作。按钮会变为“正在取消”消息,然后当操作完全停止时,变为“已取消”。
gcloud
使用 operations cancel
命令可停止正在进行的操作:
gcloud datastore operations cancel operation-name
取消正在进行的操作并不会撤消操作。取消的导出操作会在 Cloud Storage 中留下已导出的文档,而取消的导入操作会留下已对数据库进行的更新。您无法导入部分完成的导出文件。
删除操作
gcloud
使用 operations delete
命令可从近期操作列表中移除操作。此命令不会从 Cloud Storage 中删除导出文件。
gcloud datastore operations delete operation-name
代管式导出和导入操作的计费与价格
在使用代管式导出和导入服务前,您需要为 Google Cloud 项目启用结算功能。导出和导入操作通过以下方式计入 Google Cloud 费用:
- 导出和导入操作执行的实体读取与写入计入您的 Datastore 模式 Firestore 费用。导出操作会对每个导出的实体执行一次读取操作。导入操作会对每个导入的实体执行一次写入操作。
- 存储在 Cloud Storage 中的输出文件计入您的 Cloud Storage 数据存储费用。
导出或导入操作在完成之前不会触发任何 Google Cloud 预算提醒。同样,操作完成后,在导出或导入操作期间执行的读写数会计入您的每日配额。
查看导出和导入费用
导出和导入操作会为收费操作添加 goog-firestoremanaged:exportimport
标签。在 Cloud Billing 报告页面中,您可以使用此标签查看与导入和导出操作相关的费用:
与 Datastore 管理员备份的区别
如果您之前使用过 Datastore 管理员控制台进行备份,则应注意以下差异:
托管式导出所创建的导出操作不会出现在 Datastore 管理控制台中。托管式导出和导入是一项新服务,不会与 App Engine 的备份和恢复功能共享数据(您可通过 Google Cloud 控制台管理此功能)。
代管式导出和导入服务不支持与 Datastore 管理员备份相同的元数据,也不会将进度状态存储在数据库中。如需了解如何检查导出和导入操作的进度,请参阅管理长时间运行的操作
您无法查看代管式导出和导入操作的服务日志。
托管式导入服务向后兼容 Datastore 管理员备份文件。您可以使用代管式导入服务导入 Datastore 管理员备份文件,但无法使用 Datastore 管理员控制台导入代管式导出操作的输出。
导入到 BigQuery
如需通过代管式导出操作将数据导入到 BigQuery,请参阅加载 Datastore 导出服务数据。
如果在未指定实体过滤条件的情况下导出了数据,则该数据无法加载到 BigQuery 中。如果您想要将数据导入到 BigQuery,则您的导出请求的实体过滤条件中必须包含一个或多个种类名称。
BigQuery 列限制
BigQuery 对每个表施加的列数上限为 10000。导出操作会为每个种类生成 BigQuery 表架构。在此架构中,种类实体内的每个唯一属性都会变为架构列。
如果种类的 BigQuery 架构超过 10000 列,则导出操作会尝试将嵌入式实体视为 Blob,从而保持在列限制以下。如果此转化使架构中的列数低于 10000,您可以将数据加载到 BigQuery 中,但无法查询嵌入式实体中的属性。 如果列数仍然超过 10000,则导出操作不会为该种类生成 BigQuery 架构,而且您无法将其数据加载到 BigQuery 中。
服务代理迁移
Firestore 使用 Firestore 服务代理(而不是 App Engine 服务账号)来对导入和导出操作授权。服务代理和服务账号使用以下命名惯例:
- Firestore 服务代理
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com
Firestore 以前使用的是 App Engine 默认服务账号,而不是 Firestore 服务代理。如果您的数据库仍使用 App Engine 服务账号来导入或导出数据,我们建议您按照本部分中的说明迁移到使用 Firestore 服务代理。
- App Engine 服务账号
PROJECT_ID@appspot.gserviceaccount.com
最好使用 Firestore 服务代理,因为它专用于 Firestore。App Engine 服务账号由多项服务共享。
查看授权账号
您可以在 Google Cloud 控制台的导入/导出页面中,查看您的导入和导出操作使用哪个账号为请求授权。您还可以查看自己的数据库是否已经在使用 Firestore 服务代理。
-
在 Google Cloud 控制台中,转到数据库页面。
- 从数据库列表中选择所需的数据库。
-
在导航菜单中,点击导入/导出。
- 查看以下面的账号运行导入/导出作业标签旁边的授权账号。
如果您的项目不使用 Firestore 服务代理,则您可以使用以下任一方法迁移到 Firestore 服务代理:
- 通过检查和更新 Cloud Storage 存储桶权限来迁移项目(推荐)。
- 添加组织范围的政策限制条件来影响组织内的所有项目。
第一种方法是首选方法,因为它会将影响范围本地化到单个 Datastore 模式项目。第二种方法不是首选方法,因为它不会迁移现有 Cloud Storage 存储桶权限。但是,它能够在组织级层提供安全合规性。
检查和更新 Cloud Storage 存储桶权限以进行迁移
该迁移过程包含两个步骤:
- 更新 Cloud Storage 存储桶权限。如需了解详情,请参阅下一部分内容。
- 确认迁移到 Firestore 服务代理。
服务代理存储桶权限
对于使用其他项目中的 Cloud Storage 存储桶的任何导出或导入操作,您必须向该存储桶授予 Firestore 服务代理权限。例如,将数据移至另一个项目的操作需要访问该项目中的存储桶。否则,这些操作会在迁移到 Firestore 服务代理后失败。
属于同一项目的导入和导出工作流不需要更改权限。默认情况下,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 服务账号迁移到 Firestore 服务代理。迁移完成后将无法撤消。
-
在 Google Cloud 控制台中,转到数据库页面。
- 从数据库列表中选择所需的数据库。
-
在导航菜单中,点击导入/导出。
-
如果您的项目尚未迁移到 Firestore 服务代理,您会看到一个描述迁移的横幅和一个检查存储桶状态按钮。下一步可帮助您识别并修复潜在的权限错误。
点击检查存储桶状态。
此时系统将显示一个菜单,其中包含用于完成迁移的选项和 Cloud Storage 存储桶列表。该列表可能需要几分钟时间才能完成加载。
此列表包括最近在导入和导出操作中使用的存储桶,但目前没有为 Datastore 模式服务代理授予读写权限。
- 记下您的项目的 Datastore 模式服务代理的主账号名称。服务代理名称显示在要向其授予访问权限的服务代理标签下方。
-
对于该列表中将用于未来导入或导出操作的任何存储桶,请完成以下步骤:
-
在相应存储桶的表行中,点击修复。此操作会在新的标签页中打开该存储桶的权限页面。
- 点击添加。
- 在新的主账号字段中,输入 Firestore 服务代理的名称。
- 在选择角色字段中,选择服务代理 > Firestore Service Agent。
- 点击保存。
- 返回“Datastore 模式导入/导出”页面所在的标签页。
- 对该列表中的其他存储桶重复上述步骤。请务必查看该列表的所有页面。
-
-
点击迁移到 Firestore Service Agent。如果仍存在权限检查失败的存储桶,则您需要点击迁移来确认迁移。
迁移完成时,您会收到提醒。迁移操作无法撤消。
查看迁移状态
如需验证项目的迁移状态,请执行以下操作:
-
在 Google Cloud 控制台中,转到数据库页面。
- 从数据库列表中选择所需的数据库。
-
在导航菜单中,点击导入/导出。
-
在以下面的账号运行导入/导出作业标签旁边寻找主账号。
如果主账号是
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com
,则表示您的项目已迁移到 Firestore 服务代理。迁移操作无法撤消。如果项目尚未迁移,则该页面顶部会显示一条横幅和一个检查存储桶状态按钮。请参阅迁移到 Firestore 服务代理完成迁移。
添加组织范围的政策限制条件
-
在您的组织的政策中设置以下限制条件:
需要 Firestore 服务代理才能导入/导出 (
firestore.requireP4SAforImportExport
)。此限制条件要求导入和导出操作使用 Firestore 服务代理来授权请求。如需设置此限制条件,请参阅创建和管理组织政策。
应用此组织政策限制条件不会自动为 Firestore 服务代理授予适当的 Cloud Storage 存储桶权限。
如果该限制条件对任何导入或导出工作流造成权限错误,您可以将其停用,改为使用默认服务账号。检查和更新 Cloud Storage 存储桶权限后,您可以再次启用该限制条件。