本页介绍如何使用时间点恢复 (PITR) 来保留和恢复 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
准备工作
在开始使用 PITR 之前,请注意以下几点:
- 启用 PITR 后,您无法立即开始读取过去 7 天内的数据。
- 如果您要在创建数据库时启用 PITR,必须使用
gcloud firestore databases create
命令。使用 Google Cloud 控制台创建数据库时不支持启用 PITR。 - 启用 PITR 后,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
命令在创建数据库期间启用 PITR,如下所示:
gcloud firestore databases create\
--location=LOCATION\
[--database=DATABASE_ID; default="(default)"]\
[--type=TYPE; default="firestore-native"]\
--enable-pitr
替换各值,如下所示:
LOCATION
- 要在其中创建数据库的位置。DATABASE_ID
- 设置为数据库 ID 或(使用默认值)。TYPE
- 设置为 firestore-native。
您可以使用 gcloud firestore databases update
命令停用 PITR,如下所示:
gcloud firestore databases update\
[--database=DATABASE_ID; default="(default)"]\
--no-enable-pitr
替换各值,如下所示:
DATABASE_ID
- 设置为数据库 ID 或(使用默认值)。
获取保留期限和最早版本时间
控制台
在 Google Cloud 控制台中,转到数据库页面。
从数据库列表中选择所需的数据库。
在导航菜单中,点击灾难恢复。
在设置部分中,注意保留期限和最早版本时间。
- 保留期限:Cloud Firestore 为数据库保留所有数据版本的时长。如果停用了 PITR,该值为 1 小时;如果启用了 PITR,该值为 7 天。
- 最早版本时间:可在 PITR 窗口中读取旧版数据的最早时间戳。该值会由 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 读取方法都支持 PITR 读取,这些读取方法包括:get、list、batchGet、listCollectionIds、listDocuments、runQuery、runAggregationQuery 和 partitionQuery。
如需使用 REST 方法执行读取操作,请尝试以下方法之一:
在读取方法请求中,将
readTime
值作为支持的 PITR 时间戳传递给readOptions
方法。PITR 时间戳可以是过去一小时内的微秒精度时间戳,也可以是过去一小时之前的完整一分钟时间戳,但不得早于earliestVersionTime
。将
readTime
参数与BeginTransaction
方法一起使用,作为ReadOnly
事务的一部分以用于多次 PITR 读取。
Apache Beam
使用 Cloud FirestoreIO Apache Beam 连接器可以通过 Dataflow 大规模读取或写入 Cloud Firestore 数据库中的文档。
Cloud FirestoreIO 连接器的以下读取方法支持 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 导出付费。
导入到数据库。
按照导入所有文档中的步骤导入您导出的数据库。如果数据库中已有任何文档,这类文档将会被覆盖。