גישה לנתונים היסטוריים

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

שליחת שאילתות לנתונים בנקודת זמן מסוימת

אפשר להריץ שאילתה על נתונים היסטוריים של טבלה מכל נקודת זמן בחלון הזמן של התכונה 'מסע בזמן' באמצעות פסקה FOR SYSTEM_TIME AS OF. הסעיף הזה מקבל ביטוי קבוע של חותמת זמן ומפנה לגרסה של הטבלה שהייתה עדכנית באותה חותמת זמן. הטבלה צריכה להיות מאוחסנת ב-BigQuery, ולא יכולה להיות טבלה חיצונית. אין הגבלה על גודל הטבלה כשמשתמשים ב-SYSTEM_TIME AS OF.

לדוגמה, השאילתה הבאה מחזירה גרסה היסטורית של הטבלה מלפני שעה:

SELECT *
FROM `mydataset.mytable`
  FOR SYSTEM_TIME AS OF TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 1 HOUR);

אם חותמת הזמן מציינת זמן שקדם לחלון הזמן של המסע בזמן או לזמן שקדם ליצירת הטבלה, השאילתה תיכשל ותחזיר שגיאה כמו השגיאה הבאה:

Invalid snapshot time 1601168925462 for table
myproject:mydataset.table1@1601168925462. Cannot read before 1601573410026.

אחרי שמחליפים טבלה קיימת באמצעות ההצהרה CREATE OR REPLACE TABLE, אפשר להשתמש ב-FOR SYSTEM_TIME AS OF כדי לשאול שאילתות לגבי הגרסה הקודמת של הטבלה.

אם הטבלה נמחקה, השאילתה תיכשל ותחזיר שגיאה כמו זו שמופיעה בהמשך:

Not found: Table myproject:mydataset.table was not found in location LOCATION

שחזור טבלה מנקודת זמן מסוימת

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

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

אפשר לשחזר טבלה שנמחקה אבל עדיין נמצאת בחלון הזמן של התכונה 'מסע בזמן' על ידי העתקת הטבלה לטבלה חדשה באמצעות הכלי @<time> לציון זמן. אי אפשר להריץ שאילתה על טבלה שנמחקה, גם אם משתמשים במעצב זמן. קודם צריך לשחזר אותו.

משתמשים בתחביר הבא עם @<time> מעצב הזמן:

  • tableid@TIME כאשר TIME הוא מספר אלפיות השנייה מאז ראשית זמן יוניקס.
  • tableid@-TIME_OFFSET כאשר TIME_OFFSET הוא ההיסט היחסי מהשעה הנוכחית, באלפיות השנייה.
  • tableid@0: מציין את הנתונים ההיסטוריים הכי ישנים שזמינים.

כדי לשחזר טבלה, בוחרים באחת מהאפשרויות הבאות:

המסוף

אי אפשר לבטל את המחיקה של טבלה באמצעות מסוף Google Cloud .

BQ

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. כדי לשחזר טבלה, קודם צריך לקבוע חותמת זמן של מערכת UNIX שבה הטבלה הייתה קיימת (באלפיות השנייה). אפשר להשתמש בפקודה date של Linux כדי ליצור את חותמת הזמן של Unix מערך רגיל של חותמת זמן:

    date -d '2023-08-04 16:00:34.456789Z' +%s000
    
  3. לאחר מכן, משתמשים בפקודה bq copy עם קישוט ה-time travel‏ @<time> כדי לבצע את פעולת העתקת הטבלה.

    לדוגמה, מזינים את הפקודה הבאה כדי להעתיק את הטבלה mydataset.mytable בשעה 1418864998000 לטבלה חדשה mydataset.newtable.

    bq cp mydataset.mytable@1418864998000 mydataset.newtable
    

    (אופציונלי) מציינים את הדגל --location ומגדירים את הערך למיקום.

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

    bq cp mydataset.mytable@-3600000 mydataset.newtable
    
  4. Go

    לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Goהוראות ההגדרה שבמדריך למתחילים של BigQuery באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של BigQuery Go API.

    כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

    import (
    	"context"
    	"fmt"
    	"time"
    
    	"cloud.google.com/go/bigquery"
    )
    
    // deleteAndUndeleteTable demonstrates how to recover a deleted table by copying it from a point in time
    // that predates the deletion event.
    func deleteAndUndeleteTable(projectID, datasetID, tableID string) error {
    	// projectID := "my-project-id"
    	// datasetID := "mydataset"
    	// tableID := "mytable"
    	ctx := context.Background()
    	client, err := bigquery.NewClient(ctx, projectID)
    	if err != nil {
    		return fmt.Errorf("bigquery.NewClient: %v", err)
    	}
    	defer client.Close()
    
    	ds := client.Dataset(datasetID)
    	if _, err := ds.Table(tableID).Metadata(ctx); err != nil {
    		return err
    	}
    	// Record the current time.  We'll use this as the snapshot time
    	// for recovering the table.
    	snapTime := time.Now()
    
    	// "Accidentally" delete the table.
    	if err := client.Dataset(datasetID).Table(tableID).Delete(ctx); err != nil {
    		return err
    	}
    
    	// Construct the restore-from tableID using a snapshot decorator.
    	snapshotTableID := fmt.Sprintf("%s@%d", tableID, snapTime.UnixNano()/1e6)
    	// Choose a new table ID for the recovered table data.
    	recoverTableID := fmt.Sprintf("%s_recovered", tableID)
    
    	// Construct and run a copy job.
    	copier := ds.Table(recoverTableID).CopierFrom(ds.Table(snapshotTableID))
    	copier.WriteDisposition = bigquery.WriteTruncate
    	job, err := copier.Run(ctx)
    	if err != nil {
    		return err
    	}
    	status, err := job.Wait(ctx)
    	if err != nil {
    		return err
    	}
    	if err := status.Err(); err != nil {
    		return err
    	}
    
    	ds.Table(recoverTableID).Delete(ctx)
    	return nil
    }
    

    Java

    לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Javaהוראות ההגדרה שבמדריך למתחילים של BigQuery באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של BigQuery Java API.

    כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

    import com.google.cloud.bigquery.BigQuery;
    import com.google.cloud.bigquery.BigQueryException;
    import com.google.cloud.bigquery.BigQueryOptions;
    import com.google.cloud.bigquery.CopyJobConfiguration;
    import com.google.cloud.bigquery.Job;
    import com.google.cloud.bigquery.JobInfo;
    import com.google.cloud.bigquery.TableId;
    
    // Sample to undeleting a table
    public class UndeleteTable {
    
      public static void runUndeleteTable() {
        // TODO(developer): Replace these variables before running the sample.
        String datasetName = "MY_DATASET_NAME";
        String tableName = "MY_TABLE_TABLE";
        String recoverTableName = "MY_RECOVER_TABLE_TABLE";
        undeleteTable(datasetName, tableName, recoverTableName);
      }
    
      public static void undeleteTable(String datasetName, String tableName, String recoverTableName) {
        try {
          // Initialize client that will be used to send requests. This client only needs to be created
          // once, and can be reused for multiple requests.
          BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();
    
          // "Accidentally" delete the table.
          bigquery.delete(TableId.of(datasetName, tableName));
    
          // Record the current time.  We'll use this as the snapshot time
          // for recovering the table.
          long snapTime = System.currentTimeMillis();
    
          // Construct the restore-from tableID using a snapshot decorator.
          String snapshotTableId = String.format("%s@%d", tableName, snapTime);
    
          // Construct and run a copy job.
          CopyJobConfiguration configuration =
              CopyJobConfiguration.newBuilder(
                      // Choose a new table ID for the recovered table data.
                      TableId.of(datasetName, recoverTableName),
                      TableId.of(datasetName, snapshotTableId))
                  .build();
    
          Job job = bigquery.create(JobInfo.of(configuration));
          job = job.waitFor();
          if (job.isDone() && job.getStatus().getError() == null) {
            System.out.println("Undelete table recovered successfully.");
          } else {
            System.out.println(
                "BigQuery was unable to copy the table due to an error: \n"
                    + job.getStatus().getError());
            return;
          }
        } catch (BigQueryException | InterruptedException e) {
          System.out.println("Table not found. \n" + e.toString());
        }
      }
    }

    Node.js

    לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Node.jsהוראות ההגדרה שבמדריך למתחילים של BigQuery באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של BigQuery Node.js API.

    כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

    // Import the Google Cloud client library
    const {BigQuery} = require('@google-cloud/bigquery');
    const bigquery = new BigQuery();
    
    async function undeleteTable() {
      // Undeletes "my_table_to_undelete" from "my_dataset".
    
      /**
       * TODO(developer): Uncomment the following lines before running the sample.
       */
      // const datasetId = "my_dataset";
      // const tableId = "my_table_to_undelete";
      // const recoveredTableId = "my_recovered_table";
    
      /**
       * TODO(developer): Choose an appropriate snapshot point as epoch milliseconds.
       * For this example, we choose the current time as we're about to delete the
       * table immediately afterwards.
       */
      const snapshotEpoch = Date.now();
    
      // Delete the table
      await bigquery
        .dataset(datasetId)
        .table(tableId)
        .delete();
    
      console.log(`Table ${tableId} deleted.`);
    
      // Construct the restore-from table ID using a snapshot decorator.
      const snapshotTableId = `${tableId}@${snapshotEpoch}`;
    
      // Construct and run a copy job.
      await bigquery
        .dataset(datasetId)
        .table(snapshotTableId)
        .copy(bigquery.dataset(datasetId).table(recoveredTableId));
    
      console.log(
        `Copied data from deleted table ${tableId} to ${recoveredTableId}`
      );
    }

    Python

    לפני שמנסים את הדוגמה הזו, צריך לפעול לפי Pythonהוראות ההגדרה שבמדריך למתחילים של BigQuery באמצעות ספריות לקוח. מידע נוסף מופיע במאמרי העזרה של BigQuery Python API.

    כדי לבצע אימות ב-BigQuery, צריך להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

    import time
    
    from google.cloud import bigquery
    
    # Construct a BigQuery client object.
    client = bigquery.Client()
    
    # TODO(developer): Choose a table to recover.
    # table_id = "your-project.your_dataset.your_table"
    
    # TODO(developer): Choose a new table ID for the recovered table data.
    # recovered_table_id = "your-project.your_dataset.your_table_recovered"
    
    # TODO(developer): Choose an appropriate snapshot point as epoch
    # milliseconds. For this example, we choose the current time as we're about
    # to delete the table immediately afterwards.
    snapshot_epoch = int(time.time() * 1000)
    
    # ...
    
    # "Accidentally" delete the table.
    client.delete_table(table_id)  # Make an API request.
    
    # Construct the restore-from table ID using a snapshot decorator.
    snapshot_table_id = "{}@{}".format(table_id, snapshot_epoch)
    
    # Construct and run a copy job.
    job = client.copy_table(
        snapshot_table_id,
        recovered_table_id,
        # Must match the source and destination tables location.
        location="US",
    )  # Make an API request.
    
    job.result()  # Wait for the job to complete.
    
    print(
        "Copied data from deleted table {} to {}".format(table_id, recovered_table_id)
    )

אם אתם חושבים שאולי תרצו לשחזר טבלה מאוחר יותר ממה שמותר בחלון הזמן של התכונה 'מסע בזמן', כדאי ליצור תמונת מצב של הטבלה. מידע נוסף זמין במאמר מבוא לצילומי מצב של טבלאות.

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

המאמרים הבאים