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

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

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

הרשאות

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

  • בעלים של Cloud Datastore ‏ (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.
  • אם רוצים להפעיל 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. אפשר להשתמש בפונקציונליות של PITR רק בפרויקטים ב-Google Cloud שבהם החיוב מופעל.

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

המסוף

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

    כניסה לדף Databases

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

  3. בתפריט הניווט, לוחצים על Disaster Recovery (התאוששות מאסון).

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

  5. מסמנים את התיבה הפעלת שחזור לנקודת זמן מסוימת ולוחצים על שמירה.

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

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

gcloud

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

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

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

  • LOCATION – המיקום שבו רוצים ליצור את מסד הנתונים.
  • DATABASE_ID – מוגדר למזהה מסד נתונים.

כדי להשבית את PITR, משתמשים בפקודה gcloud firestore databases update באופן הבא:

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

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

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

קבלת תקופת השמירה והשעה של הגרסה המוקדמת ביותר

המסוף

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

    כניסה לדף Databases

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

  3. בתפריט הניווט, לוחצים על Disaster Recovery (התאוששות מאסון).

  4. בקטע הגדרות, רושמים את תקופת השמירה ואת השעה של הגרסה המוקדמת ביותר.

    • תקופת השמירה: התקופה שבה Cloud Firestore שומר את כל הגרסאות של הנתונים במסד הנתונים. הערך הוא שעה אחת כשה-PITR מושבת, ושבעה ימים כשה-PITR מופעל.
    • הזמן של הגרסה המוקדמת ביותר: חותמת הזמן המוקדמת ביותר שבה אפשר לקרוא גרסאות ישנות יותר של הנתונים בחלון PITR. הערך הזה מתעדכן כל הזמן על ידי Cloud Firestore, והוא הופך להיות לא עדכני ברגע שמבצעים שאילתה לגביו. אם אתם משתמשים בערך הזה כדי לשחזר נתונים, חשוב לקחת בחשבון את הזמן שחלף מהרגע שבו הערך נשלף ועד לרגע שבו מתחילים את השחזור.
    • שחזור מערכת מנקודה מסוימת בזמן: מוצג Enabled אם האפשרות PITR מופעלת. אם 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 ישירות בפעולות קריאה. מידע נוסף זמין במאמר Transactions and batched writes (טרנזקציות וכתיבות באצווה).

  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 ישירות בפעולות קריאה. מידע נוסף זמין במאמר Transactions and batched writes (טרנזקציות וכתיבות באצווה).

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 נתמכות בשיטת הקריאה הבאה של מחבר ה-IO‏ Cloud Firestore. שיטות הקריאה האלה תומכות בשיטה 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 עם חותמת זמן של דקה שלמה ב-7 הימים האחרונים, אבל לא לפני 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. ייבוא למסד נתונים.

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