עבודה עם שחזור בנקודת זמן (PITR)

בדף הזה נסביר איך משתמשים בשחזור לנקודת זמן מסוימת (PITR) כדי לשמור ולשחזר נתונים ב-Cloud Firestore.

במאמר שחזור מערכת מנקודה מסוימת בזמן מוסבר על המושגים של PITR.

הרשאות

כדי לקבל את ההרשאות הנדרשות לניהול ההגדרות של PITR, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט שבו אתם רוצים להפעיל את PITR:

  • 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, חשוב לשים לב לנקודות הבאות:

  • אי אפשר להתחיל לקרוא מ-7 ימים אחורה מיד אחרי הפעלת PITR.
  • כדי להפעיל את PITR בזמן יצירת מסד נתונים, צריך להשתמש בפקודה gcloud firestore databases create. אי אפשר להפעיל את PITR בזמן יצירת מסד נתונים באמצעות מסוף Google Cloud.
  • Cloud Firestore מתחיל לשמור גרסאות מהנקודה הזו ואילך אחרי הפעלת PITR.
  • לא ניתן לקרוא נתוני PITR בחלון PITR אחרי השבתת PITR.
  • אם תפעילו מחדש את PITR מיד אחרי השבתתו, נתוני PITR הקודמים כבר לא יהיו זמינים. כל נתוני PITR שנוצרו לפני השבתת PITR יימחקו אחרי תאריך התפוגה של PITR.
  • אם מחקתם בטעות נתונים בשעה האחרונה ו-PITR מושבת, תוכלו להפעיל את PITR תוך שעה ממועד המחיקה כדי לשחזר את הנתונים.
  • כל קריאה שמתבצעת בנתוני PITR שפג תוקפם נכשלת.

הפעלת PITR

לפני שמשתמשים ב-PITR, צריך להפעיל את החיוב בפרויקט ב-Google Cloud. רק בפרויקטים ב-Google Cloud שבהם החיוב מופעל אפשר להשתמש בפונקציה של PITR.

כדי להפעיל את PITR במסד הנתונים:

המסוף

  1. נכנסים לדף Databases במסוף Google Cloud.

    כניסה לדף Databases

  2. בוחרים את מסד הנתונים הנדרש מרשימת מסדי הנתונים.

  3. בתפריט הניווט, לוחצים על Disaster Recovery.

  4. לוחצים על עריכה כדי לערוך את ההגדרות.

  5. מסמנים את התיבה Enable point-in-time recovery (הפעלת שחזור לנקודת זמן ספציפית) ולוחצים על Save (שמירה).

הפעלת PITR כרוכה בעלויות אחסון. מידע נוסף זמין במאמר תמחור.

כדי להשבית את PITR, מבטלים את הסימון בתיבה Enable point-in-time recovery בדף Disaster Recovery במסוף Google Cloud.

gcloud

מפעילים את PITR במהלך יצירת מסד הנתונים באמצעות הפקודה gcloud firestore databases create באופן הבא:

gcloud firestore databases create\
  --location=LOCATION\
  [--database=DATABASE_ID; default="(default)"]\
  [--type=TYPE; default="firestore-native"]\
  --enable-pitr

מחליפים את הערכים באופן הבא:

  • LOCATION – המיקום שבו רוצים ליצור את מסד הנתונים.
  • DATABASE_ID – מוגדר למזהה של מסד הנתונים או ל-(ברירת המחדל).
  • TYPE – מוגדר לערך firestore-native.

אפשר להשבית את PITR באמצעות הפקודה gcloud firestore databases update באופן הבא:

gcloud firestore databases update\
  [--database=DATABASE_ID; default="(default)"]\
  --no-enable-pitr

מחליפים את הערכים באופן הבא:

  • DATABASE_ID – מוגדר למזהה מסד הנתונים או ל-(ברירת המחדל).

אחזור של תקופת השמירה וזמן הגרסה המוקדמת ביותר

המסוף

  1. נכנסים לדף Databases במסוף Google Cloud.

    כניסה לדף Databases

  2. בוחרים את מסד הנתונים הנדרש מרשימת מסדי הנתונים.

  3. בתפריט הניווט, לוחצים על Disaster Recovery.

  4. בקטע Settings, שימו לב לRetention period ולEarliest version time.

    • תקופת השמירה: התקופה שבה Cloud Firestore שומרת את כל הגרסאות של הנתונים של מסד הנתונים. הערך הוא שעה אחת כש-PITR מושבת, ושבעה ימים כש-PITR מופעל.
    • Earliest version time: חותמת הזמן המוקדם ביותר שבה אפשר לקרוא גרסאות ישנות יותר של הנתונים בחלון ה-PITR. הערך הזה מתעדכן באופן קבוע על ידי Cloud Firestore והוא הופך ללא רלוונטי ברגע שמתבצעת שאילתה עליו. אם אתם משתמשים בערך הזה כדי לשחזר נתונים, חשוב להביא בחשבון את הזמן שחלף מהרגע שבו נשלחה השאילתה לגבי הערך ועד לרגע שבו אתם מפעילים את השחזור.
    • שחזור מערכת מנקודה מסוימת בזמן: אם התכונה PITR מופעלת, יוצג הערך Enabled. אם התכונה PITR מושבתת, יופיע הערך 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 אם התכונה PITR מופעלת. אם התכונה PITR מושבתת, יופיע הערך POINT_IN_TIME_RECOVERY_DISABLED או שהשדה pointInTimeRecoveryEnablement לא יוצג.
  • versionRetentionPeriod: תקופת הזמן שבה נתוני PITR נשמרים, באלפיות השנייה. הערך יכול להיות שעה אחת כש-PITR מושבת או שבעה ימים אם PITR מופעל.

קריאת נתוני PITR

אפשר לקרוא נתוני PITR באמצעות ספריות הלקוח, שיטות ה-API ל-REST או המחבר 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)}
  )

API ל-REST

קריאות PITR נתמכות בכל שיטות הקריאה של Cloud Firestore, שהן: get,‏ list,‏ batchGet,‏ listCollectionIds,‏ listDocuments,‏ runQuery,‏ runAggregationQuery ו-partitionQuery.

כדי לבצע קריאה באמצעות שיטות ה-REST, אפשר לנסות את אחת מהאפשרויות הבאות:

  1. בבקשה של שיטת הקריאה, מעבירים את הערך readTime כחותמת זמן נתמכת של PITR בשיטה readOptions. חותמת זמן של PITR יכולה להיות חותמת זמן ברמת דיוק של מיליונים של שנייה מהשעה האחרונה, או חותמת זמן של דקה שלמה מעבר לשעה האחרונה, אבל לא לפני earliestVersionTime.

  2. משתמשים בפרמטר readTime יחד עם השיטה BeginTransaction כחלק מעסקה מסוג ReadOnly עבור מספר קריאות PITR.

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.

ייצוא וייבוא מנתוני 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 – חותמת זמן של PITR ברמת פירוט של דקה, למשל 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. ייבוא למסד נתונים.

    כדי לייבא את מסד הנתונים שיוצאתם, פועלים לפי השלבים שמפורטים במאמר ייבוא כל המסמכים. אם כבר קיים מסמך כלשהו במסד הנתונים, הוא יוחלף.