适用于 Cloud Firestore 标准版和 Cloud Firestore 企业版。 |
本页介绍如何使用时间点恢复 (PITR) 来保留和恢复具有 MongoDB 兼容性的 Cloud Firestore 中的数据。
如需了解 PITR 概念,请参阅时间点恢复。
权限
如需获取管理 PITR 设置所需的权限,请让管理员向您授予您想要启用 PITR 的项目的以下 IAM 角色:
- Cloud Datastore Owner (
roles/datastore.owner
)
对于自定义角色,请确保已为其授予以下权限:
- 如需在创建数据库时启用 PITR:
datastore.databases.create
- 如需更新现有数据库上的 PITR 设置:
datastore.databases.update
、datastore.databases.list
- 如需从 PITR 数据进行读取:
datastore.databases.get
、datastore.entities.get
、datastore.entities.list
- 如需导出 PITR 数据:
datastore.databases.export
- 如需导入 PITR 数据:
datastore.databases.import
- 如需克隆数据库,请执行以下操作:
datastore.databases.clone
准备工作
在开始使用 PITR 之前,请注意以下几点:
- 启用 PITR 后,您无法立即开始读取过去 7 天内的数据。
- 如果您要在创建数据库时启用 PITR,必须使用
gcloud firestore databases create
命令。使用 Google Cloud 控制台创建数据库时不支持启用 PITR。 - 启用 PITR 后,与 MongoDB 兼容的 Cloud Firestore 会立即开始保留版本。
- 停用 PITR 后,您将无法在 PITR 窗口中读取 PITR 数据。
- 如果您在停用 PITR 后立即将其重启,则过去的 PITR 数据将不再可用。系统将在 PITR 失效日期之后删除停用 PITR 之前创建的任何 PITR 数据。
- 如果您在过去一小时内不小心删除了数据并停用了 PITR,则可以在删除后的一小时内启用 PITR,从而恢复数据。
- 对已过期的 PITR 数据执行的任何读取操作都会失败。
启用 PITR
在使用 PITR 之前,请为 Google Cloud 项目启用结算功能。只有启用了结算功能的 Google Cloud 项目才能使用 PITR 功能。
如需为数据库启用 PITR,请执行以下操作:
控制台
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击灾难恢复。
点击修改以修改设置。
选中启用时间点恢复复选框,然后点击保存。
启用 PITR 会产生存储费用。如需了解详情,请参阅价格。
如需停用 PITR,请在 Google Cloud 控制台的“灾难恢复”页面中取消选中启用时间点恢复复选框。
gcloud
您可以在创建数据库期间使用 gcloud firestore databases create
和 --enable-ptir
命令启用 PITR,如下所示:
gcloud firestore databases create\
--location=LOCATION\
--database=DATABASE_ID\
--type=firestore-native\
--enable-pitr
替换各值,如下所示:
LOCATION
- 要在其中创建数据库的位置。DATABASE_ID
- 设置为数据库 ID。
您可以使用 gcloud firestore databases update
命令停用 PITR,如下所示:
gcloud firestore databases update\
--database=DATABASE_ID\
--no-enable-pitr
替换各值,如下所示:
DATABASE_ID
- 设置为数据库 ID 或(使用默认值)。
获取保留期限和最早版本时间
控制台
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击灾难恢复。
在设置部分中,注意保留期限和最早版本时间。
- 保留期限:与 MongoDB 兼容的 Cloud Firestore 为数据库保留所有数据版本的时长。如果停用了 PITR,该值为 1 小时;如果启用了 PITR,该值为 7 天。
- 最早版本时间:可在 PITR 窗口中读取旧版数据的最早时间戳。该值会由与 MongoDB 兼容的 Cloud Firestore 不断更新,并且会在查询时过时。如果您使用该值恢复数据,请确保计算从发出查询到查询恢复那一刻这段时间。
- 时间点恢复:如果启用了 PITR,则显示
Enabled
。如果停用了 PITR,您会看到Disabled
。
gcloud
运行 gcloud firestore databases describe 命令,如下所示:
gcloud firestore databases describe --database=DATABASE_ID
将 DATABASE_ID
替换为数据库 ID 或 '(default)'
。
输出如下:
appEngineIntegrationMode: ENABLED
concurrencyMode: PESSIMISTIC
createTime: '2021-03-24T17:02:35.234Z'
deleteProtectionState: DELETE_PROTECTION_DISABLED
earliestVersionTime: '2023-06-12T16:17:25.222474Z'
etag: IIDayqOevv8CMNTvyNK4uv8C
keyPrefix: s
locationId: nam5
name: projects/PROJECT_ID/databases/DATABASE_ID
pointInTimeRecoveryEnablement: POINT_IN_TIME_RECOVERY_DISABLED
type: FIRESTORE_NATIVE
uid: 5230c382-dcd2-468f-8cb3-2a1acfde2b32
updateTime: '2021-11-17T17:48:22.171180Z'
versionRetentionPeriod: 3600s
其中
earliestVersionTime
:最早存储的 PITR 数据的时间戳。pointInTimeRecoveryEnablement
:如果启用了 PITR,则显示POINT_IN_TIME_RECOVERY_ENABLED
。如果停用了 PITR,您会看到POINT_IN_TIME_RECOVERY_DISABLED
,或者pointInTimeRecoveryEnablement
字段可能不会显示。versionRetentionPeriod
:保留 PITR 数据的时间段(以毫秒为单位)。如果停用 PITR,该值可能是 1 小时;如果启用了 PITR,则可能是 7 天。
读取 PITR 数据
您可以使用客户端库、REST API 方法或 FirestoreIO Apache Beam 连接器读取 PITR 数据。客户端库
Java
您必须使用 ReadOnly
事务来读取 PITR 数据。您不能在读取操作中直接指定 readTime
。如需了解详情,请参阅事务和批量写入。
Firestore firestore = …
TransactionOptions options =
TransactionOptions.createReadOnlyOptionsBuilder()
.setReadTime(
com.google.protobuf.Timestamp.newBuilder()
.setSeconds(1684098540L)
.setNanos(0))
.build();
ApiFuture<Void> futureTransaction = firestore.runTransaction(
transaction -> {
// Does a snapshot read document lookup
final DocumentSnapshot documentResult =
transaction.get(documentReference).get();
// Executes a snapshot read query
final QuerySnapshot queryResult =
transaction.get(query).get();
},
options);
// Blocks on transaction to complete
futureTransaction.get();
节点
您必须使用 ReadOnly
事务来读取 PITR 数据。您不能在读取操作中直接指定 readTime
。如需了解详情,请参阅事务和批量写入。
const documentSnapshot = await firestore.runTransaction(
updateFunction => updateFunction.get(documentRef),
{readOnly: true, readTime: new Firestore.Timestamp(1684098540, 0)}
);
const querySnapshot = await firestore.runTransaction(
updateFunction => updateFunction.get(query),
{readOnly: true, readTime: new Firestore.Timestamp(1684098540, 0)}
);
REST API
所有 Cloud Firestore with MongoDB compatibility 读取方法都支持 PITR 读取,这些读取方法包括:get、list、batchGet、listCollectionIds、listDocuments、runQuery、runAggregationQuery 和 partitionQuery。
如需使用 REST 方法执行读取操作,请尝试以下方法之一:
在读取方法请求中,将
readTime
值作为支持的 PITR 时间戳传递给readOptions
方法。PITR 时间戳可以是过去一小时内的微秒精度时间戳,也可以是过去一小时之前的完整一分钟时间戳,但不得早于earliestVersionTime
。将
readTime
参数与BeginTransaction
方法一起使用,作为ReadOnly
事务的一部分以用于多次 PITR 读取。
Apache Beam
使用 Cloud Firestore with MongoDB compatibilityIO Apache Beam 连接器可以通过 Dataflow 大规模读取或写入 Cloud Firestore with MongoDB compatibility 数据库中的文档。
Cloud Firestore with MongoDB compatibilityIO 连接器的以下读取方法支持 PITR 读取。这些读取方法支持可用于 PITR 读取的 withReadTime(@Nullable Instant readTime)
方法:
- FirestoreV1.BatchGetDocuments
- FirestoreV1.ListCollectionIds
- FirestoreV1.ListDocuments
- FirestoreV1.PartitionQuery
Java
以下代码可以与示例 Dataflow 流水线代码搭配使用,以执行批量读取或写入操作。该示例使用 withReadTime(@Nullable Instant readTime)
方法进行 PITR 读取。
Instant readTime = Instant.ofEpochSecond(1684098540L);
PCollection<Document> documents =
pipeline
.apply(Create.of(collectionId))
.apply(
new FilterDocumentsQuery(
firestoreOptions.getProjectId(), firestoreOptions.getDatabaseId()))
.apply(FirestoreIO.v1().read().runQuery().withReadTime(readTime).withRpcQosOptions(rpcQosOptions).build())
...
如需查看 Dataflow 流水线中 readTime
示例的完整列表,请参阅 GitHub 代码库。
从 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
其中:
BUCKET_NAME_PATH
- 有效的 Cloud Storage 存储桶(包含可选路径前缀),用于存储导出文件。PITR_TIMESTAMP
- 分钟粒度的 PITR 时间戳,例如2023-05-26T10:20:00.00Z
或2023-10-19T10:30:00.00-07:00
。COLLECTION_IDS
- 集合 ID 或集合组 ID 的列表,例如'specific-collection-group1','specific-collection-group2'
。NAMESPACE_IDS
- 命名空间 ID 的列表,例如'customer','orders'
。
在导出 PITR 数据之前,请注意以下几点:
- 以 RFC 3339 格式指定时间戳。例如
2023-05-26T10:20:00.00Z
或2023-10-19T10:30:00.00-07:00
。 - 请确保您指定的时间戳是过去七天内的整分钟时间戳,但不早于
earliestVersionTime
。如果指定的时间戳已不存在数据,则会生成错误。 时间戳必须是整分钟,即使指定的时间在过去一小时内也是如此。 - 您无需为失败的 PITR 导出付费。
导入到数据库。
按照导入所有文档中的步骤导入您导出的数据库。如果数据库中已有任何文档,这类文档将会被覆盖。
从数据库克隆
您可以将现有数据库在选定时间点的数据克隆到新的数据库中:
克隆的数据库是一个新数据库,将在源数据库所在的同一位置创建。
为了创建克隆,Cloud Firestore 使用源数据库的时间点恢复 (PITR) 数据。克隆的数据库包含所有数据和索引。
默认情况下,克隆的数据库将采用与源数据库相同的加密方式(Google 默认加密或 CMEK 加密)。您可以指定其他加密类型,也可以使用其他密钥进行 CMEK 加密。
时间戳的粒度为 1 分钟,它指定了过去的一个时间点,该时间点必须在 PITR 时间窗口定义的时段内:
- 如果数据库已启用 PITR,您可以选择过去 7 天内的任意一分钟(如果 PITR 启用时间不足 7 天,则可选择启用以来的任意一分钟)。
- 如果未启用 PITR,您可以选择过去一小时内的任意一分钟。
- 您可以在数据库的说明中查看可选择的最早时间戳。
控制台
Firebase 控制台不支持克隆数据库。您可以按照 Google Cloud CLI 的说明克隆数据库。
gcloud
使用 gcloud alpha firestore databases clone
命令克隆数据库:
gcloud alpha firestore databases clone \
--source-database='SOURCE_DATABASE' \
--snapshot-time='PITR_TIMESTAMP' \
--destination-database='DESTINATION_DATABASE_ID'
替换以下内容:
SOURCE_DATABASE:您要克隆的现有数据库的数据库名称。名称采用
projects/PROJECT_ID/databases/SOURCE_DATABASE_ID
格式。PITR_TIMESTAMP:采用 RFC 3339 格式的 PITR 时间戳,精确到分钟。例如:
2025-06-01T10:20:00.00Z
或2025-06-01T10:30:00.00-07:00
。DESTINATION_DATABASE_ID:新克隆数据库的数据库 ID。此数据库 ID 必须与现有数据库无关联。
示例:
gcloud alpha firestore databases clone \
--source-database='projects/example-project/databases/(default)' \
--snapshot-time='2025-06-01T10:20:00.00Z' \
--destination-database='projects/example-project/databases/example-dest-db'
更改克隆数据库的加密配置
默认情况下,克隆的数据库将具有与源数据库相同的加密配置。如需更改加密配置,请使用 --encryption-type
参数:
- (默认)
use-source-encryption
:使用与源数据库相同的加密配置。 google-default-encryption
:使用 Google 的默认加密方式。customer-managed-encryption
:使用 CMEK 加密。在--kms-key-name
参数中指定密钥 ID。
以下示例展示了如何为克隆的数据库配置 CMEK 加密:
gcloud alpha firestore databases clone \
--source-database='projects/example-project/databases/(default)' \
--snapshot-time='2025-06-01T10:20:00.00Z' \
--destination-database='projects/example-project/databases/example-dest-db' \
--encryption-type='customer-managed-encryption' \
--kms-key-name='projects/example-project/locations/us-central1/keyRings/example-key-ring/cryptoKeys/example-key'