Как работать с восстановлением на определенный момент времени (PITR)

На этой странице описано, как использовать восстановление на определенный момент времени (PITR) для хранения и восстановления данных в Cloud Firestore.

Чтобы узнать больше о восстановлении на определенный момент времени, ознакомьтесь с этой статьей.

Разрешения

Чтобы получить разрешения, необходимые для управления настройками восстановления на определенный момент времени, попросите администратора назначить вам следующие роли IAM в проекте, в котором вы хотите включить восстановление на определенный момент времени:

  • Владелец Cloud Datastore (roles/datastore.owner)

Для специальных ролей убедитесь, что предоставлены следующие разрешения:

  • Чтобы включить восстановление на определенный момент времени при создании базы данных: datastore.databases.create
  • Чтобы обновить настройки восстановления на определенный момент времени в существующей базе данных, выполните следующие действия: 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.
  • Если вы хотите включить PITR при создании базы данных, используйте команду gcloud firestore databases create. Включить восстановление на определенный момент времени при создании базы данных в консоли Google Cloud нельзя.
  • Cloud Firestore начинает сохранять версии с момента включения PITR.
  • После отключения PITR вы не сможете читать данные в окне PITR.
  • Если вы повторно включите восстановление на определенный момент времени сразу после отключения, данные за прошлые периоды будут недоступны. Все данные PITR, созданные до отключения PITR, будут удалены после истечения срока действия PITR.
  • Если вы случайно удалили данные в течение последнего часа и восстановление на определенный момент времени отключено, вы можете восстановить данные, включив восстановление на определенный момент времени в течение одного часа после удаления.
  • Любая попытка чтения данных PITR с истекшим сроком действия завершается ошибкой.

Включить восстановление на определенный момент времени

Прежде чем использовать PITR, включите платежные функции для проекта Google Cloud. Функция PITR доступна только в облачных проектах Google Cloud с включенными платежными функциями.

Чтобы включить PITR для базы данных:

Консоль

  1. В консоли Google Cloud перейдите на страницу Databases (Базы данных).

    Перейти к базам данных

  2. Выберите нужную базу данных из списка.

  3. В меню навигации выберите Аварийное восстановление.

  4. Нажмите Изменить, чтобы изменить настройки.

  5. Установите флажок Включить восстановление на определенный момент времени и нажмите Сохранить.

Включение PITR приводит к расходам на хранение. Подробнее о ценах…

Чтобы отключить восстановление на определенный момент времени, снимите флажок Включить восстановление на определенный момент времени на странице "Аварийное восстановление" в консоли Google Cloud.

gcloud

Включите восстановление на определенный момент времени при создании базы данных с помощью команды gcloud firestore databases create и --enable-ptir, как показано ниже.

gcloud firestore databases create\
  --location=LOCATION\
  --database=DATABASE_ID\
  --type=firestore-native\
  --enable-pitr

Замените значения следующим образом:

  • LOCATION – местоположение, в котором вы хотите создать базу данных.
  • DATABASE_ID – идентификатор базы данных.

Вы можете отключить восстановление на определенный момент времени с помощью команды gcloud firestore databases update:

gcloud firestore databases update\
  --database=DATABASE_ID\
  --no-enable-pitr

Замените значения следующим образом:

  • DATABASE_ID – идентификатор базы данных или (default).

Как узнать срок хранения и время создания самой ранней версии

Консоль

  1. В консоли Google Cloud перейдите на страницу Databases (Базы данных).

    Перейти к базам данных

  2. Выберите нужную базу данных из списка.

  3. В меню навигации выберите Аварийное восстановление.

  4. В разделе Настройки обратите внимание на поля Срок хранения и Время самой ранней версии.

    • Срок хранения. Период, в течение которого Cloud Firestore хранит все версии данных для базы данных. Если восстановление на определенный момент времени отключено, то значение равно одному часу, а если включено – семи дням.
    • Время самой ранней версии. Самая ранняя временная метка, по которой можно прочитать старые версии данных в окне восстановления на определенный момент времени. Это значение постоянно обновляется Cloud Firestore и устаревает в момент запроса. Если вы используете это значение для восстановления данных, обязательно учитывайте время с момента запроса значения до момента начала восстановления.
    • Восстановление на определенный момент времени. Если оно включено, вы увидите Enabled. Если восстановление на определенный момент времени отключено, вы увидите Disabled.

gcloud

Выполните команду gcloud firestore databases describe, как показано ниже.

gcloud firestore databases describe --database=DATABASE_ID

Замените DATABASE_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: показывает POINT_IN_TIME_RECOVERY_ENABLED, если включено восстановление на определенный момент времени. Если восстановление на определенный момент времени отключено, вы увидите POINT_IN_TIME_RECOVERY_DISABLED или поле pointInTimeRecoveryEnablement не будет отображаться.
  • versionRetentionPeriod – период времени в миллисекундах, в течение которого хранятся данные PITR. Если восстановление на определенный момент времени отключено, значение может быть равно одному часу, а если включено – семи дням.

Чтение данных PITR

Вы можете читать данные PITR, используя клиентские библиотеки, методы REST API или коннектор FirestoreIO Apache Beam.

Клиентские библиотеки

Java

Для чтения данных PITR необходимо использовать транзакцию ReadOnly. Вы не можете напрямую указать 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();

Узел

Для чтения данных PITR необходимо использовать транзакцию ReadOnly. Вы не можете напрямую указать 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

Чтение PITR поддерживается во всех методах чтения Cloud Firestore, а именно: get, list, batchGet, listCollectionIds, listDocuments, runQuery, runAggregationQuery и partitionQuery.

Чтобы выполнить чтение с помощью методов REST, попробуйте один из следующих вариантов:

  1. В запросе метода чтения передайте значение readTime в качестве поддерживаемой временной метки PITR в методе readOptions. Временная метка PITR может быть либо временной меткой с точностью до микросекунды в течение последнего часа, либо временной меткой с точностью до минуты за пределами последнего часа, но не ранее earliestVersionTime.

  2. Используйте параметр readTime вместе с методом BeginTransaction в рамках транзакции ReadOnly для нескольких операций чтения с восстановлением на определенный момент времени.

Apache Beam

Используйте коннектор Cloud FirestoreIO Apache Beam, чтобы читать и записывать документы в базе данных Cloud Firestore в больших масштабах с помощью Dataflow.

Чтение PITR поддерживается в следующем методе чтения коннектора Cloud FirestoreIO. Эти методы чтения поддерживают метод withReadTime(@Nullable Instant readTime), который можно использовать для чтения PITR:

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())
  ...

Полный список примеров readTime в конвейере Dataflow можно найти в репозитории GitHub.

Клонирование из базы данных

Вы можете клонировать существующую базу данных с выбранной временной меткой в новую базу данных:

  • Клонированная база данных – это новая база данных, которая будет создана в том же месте, что и исходная.

    Для создания клона Cloud Firestore использует данные восстановления на определенный момент времени (PITR) исходной базы данных. Клонированная база данных включает все данные и индексы.

  • По умолчанию клонированная база данных будет зашифрована так же, как и исходная, с использованием шифрования Google по умолчанию или шифрования CMEK. Вы можете указать другой тип шифрования или использовать другой ключ для шифрования CMEK.

  • Временная метка имеет детализацию в одну минуту и указывает на момент времени в прошлом, в периоде, определенном окном PITR:

    • Если для базы данных включено восстановление на определенный момент времени, вы можете выбрать любую минуту за последние семь дней (или меньше, если восстановление было включено менее семи дней назад).
    • Если восстановление на определенный момент времени не включено, вы можете выбрать любую минуту за последний час.
    • Самую раннюю временную метку, которую можно выбрать, вы найдете в описании базы данных.

Консоль

Консоль Firebase не поддерживает клонирование баз данных. Для клонирования баз данных можно использовать инструкции для Google Cloud CLI.

gcloud

Чтобы клонировать базу данных, используйте команду gcloud firestore databases clone:

gcloud firestore databases clone \
--source-database='SOURCE_DATABASE' \
--snapshot-time='PITR_TIMESTAMP' \
--destination-database='DESTINATION_DATABASE_ID'

Замените следующее:

Пример:

gcloud firestore databases clone \
--source-database='projects/example-project/databases/(default)' \
--snapshot-time='2025-06-01T10:20:00.00Z' \
--destination-database='example-dest-db'

Если вы хотите привязать некоторые теги при клонировании базы данных, используйте предыдущую команду с флагом --tags, который представляет собой необязательный список пар КЛЮЧ=ЗНАЧЕНИЕ тегов для привязки.

Пример:

gcloud firestore databases clone \
--source-database='projects/example-project/databases/(default)' \
--snapshot-time='2025-06-01T10:20:00.00Z' \
--destination-database='example-dest-db' \
--tags=key1=value1,key2=value2

По умолчанию у клонированной базы данных будет та же конфигурация шифрования, что и у исходной. Чтобы изменить конфигурацию шифрования, используйте аргумент --encryption-type:

  • use-source-encryption (по умолчанию) – использовать ту же конфигурацию шифрования, что и в исходной базе данных.
  • google-default-encryption – использовать стандартное шифрование Google.
  • customer-managed-encryption: использовать шифрование CMEK. Укажите идентификатор ключа в аргументе --kms-key-name.

В следующем примере показано, как настроить шифрование CMEK для клонированной базы данных:

gcloud firestore databases clone \
--source-database='projects/example-project/databases/(default)' \
--snapshot-time='2025-06-01T10:20:00.00Z' \
--destination-database='example-dest-db' \
--encryption-type='customer-managed-encryption' \
--kms-key-name='projects/example-project/locations/us-central1/keyRings/example-key-ring/cryptoKeys/example-key'

интерфейс командной строки Firebase

Чтобы клонировать базу данных, используйте команду firebase firestore:databases:clone:

firebase firestore:databases:clone \
'SOURCE_DATABASE' \
'DESTINATION_DATABASE' \
--snapshot-time 'PITR_TIMESTAMP'

Замените следующее:

  • SOURCE_DATABASE – название существующей базы данных, которую вы хотите клонировать. Название должно быть указано в формате projects/PROJECT_ID/databases/SOURCE_DATABASE_ID.

  • DESTINATION_DATABASE: название новой клонированной базы данных. Название должно быть указано в формате projects/PROJECT_ID/databases/DESTINATION_DATABASE_ID. Это название не должно быть связано с существующей базой данных.

  • PITR_TIMESTAMP – временная метка восстановления на определенный момент времени в формате RFC 3339 с точностью до минуты. Примеры: 2025-06-01T10:20:00.00Z или 2025-06-01T10:30:00.00-07:00. Если не указано, будет выбрано текущее время, округленное до минуты.

По умолчанию у клонированной базы данных будет та же конфигурация шифрования, что и у исходной. Чтобы изменить конфигурацию шифрования, используйте аргумент --encryption-type:

  • USE_SOURCE_ENCRYPTION (по умолчанию) – использовать ту же конфигурацию шифрования, что и в исходной базе данных.
  • GOOGLE_DEFAULT_ENCRYPTION – использовать стандартное шифрование Google.
  • CUSTOMER_MANAGED_ENCRYPTION: использовать шифрование CMEK. Укажите идентификатор ключа в аргументе --kms-key-name.

В следующем примере показано, как настроить шифрование CMEK для клонированной базы данных:

firebase firestore:databases:clone \
'projects/example-project/databases/(default)' \
'projects/example-project/databases/example-dest-db' \
--snapshot-time 'PITR_TIMESTAMP' \
--encryption-type CUSTOMER_MANAGED_ENCRYPTION

Ограничения

При клонировании не копируются данные поиска App Engine и объекты blob из базы данных (default). Эти данные действительны только для базы данных (default) и не будут полезны, если вы клонируете из (default) в базу данных, которая не поддерживает такие данные, поэтому они исключаются из клонов.

Экспорт и импорт данных PITR

Вы можете экспортировать базу данных в Cloud Storage из данных PITR с помощью команды gcloud firestore export. Вы можете экспортировать данные 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
    

    где:

    • BUCKET_NAME_PATH – действительный сегмент Cloud Storage с необязательным префиксом пути, по которому хранятся экспортированные файлы.
    • PITR_TIMESTAMP – временная метка восстановления на определенный момент времени с точностью до минуты, например 2023-05-26T10:20:00.00Z или 2023-10-19T10:30:00.00-07:00.
    • COLLECTION_IDS – список идентификаторов коллекций или групп коллекций, например 'specific-collection-group1','specific-collection-group2'.
    • NAMESPACE_IDS – список идентификаторов пространства имен, например 'customer','orders'.

    Прежде чем экспортировать данные PITR, обратите внимание на следующее:

    • Укажите временную метку в формате RFC 3339. Примеры: 2023-05-26T10:20:00.00Z или 2023-10-19T10:30:00.00-07:00.
    • Убедитесь, что указанная временная метка относится к целой минуте в течение последних семи дней, но не ранее earliestVersionTime. Если данные, соответствующие указанной временной метке, больше не существуют, будет возвращена ошибка. Временная метка должна быть целой минутой, даже если указанное время относится к последнему часу.
    • За неудачный экспорт PITR плата не взимается.
  2. Импортировать в базу данных.

    Чтобы импортировать экспортированную базу данных, выполните действия, описанные в разделе Импорт всех документов. Если какой-либо документ уже существует в вашей базе данных, он будет перезаписан.