Auf Verlaufsdaten zugreifen

Mit BigQuery können Sie Daten abfragen und wiederherstellen, die in BigQuery gespeichert sind und innerhalb Ihres Zeitreisen-Zeitraums geändert oder gelöscht wurden.

Daten zu einem bestimmten Zeitpunkt abfragen

Sie können die Verlaufsdaten einer Tabelle zu einem beliebigen Zeitpunkt innerhalb des Zeitreisefensters mit einer FOR SYSTEM_TIME AS OF-Klausel abfragen. Diese Klausel verwendet einen konstanten Zeitstempelausdruck und verweist auf die Version der Tabelle, die zu diesem Zeitstempel aktuell war. Die Tabelle muss in BigQuery gespeichert sein. Es darf keine externe Tabelle sein. Bei der Verwendung von SYSTEM_TIME AS OF ist die Tabellengröße nicht begrenzt.

Die folgende Abfrage gibt beispielsweise eine frühere Version der Tabelle von vor einer Stunde zurück:

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

Wenn im Zeitstempel eine Zeit vor dem Zeitreisefensters oder vor dem Erstellen der Tabelle angegeben ist, schlägt die Abfrage fehl und gibt einen Fehler wie den folgenden zurück:

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

Nachdem Sie eine vorhandene Tabelle mithilfe der Anweisung CREATE OR REPLACE TABLE ersetzt haben, können Sie die vorherige Version der Tabelle mit FOR SYSTEM_TIME AS OF abfragen.

Wenn die Tabelle gelöscht wurde, schlägt die Abfrage fehl und gibt einen Fehler wie den folgenden zurück:

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

Tabelle auf dem Stand eines bestimmten Zeitpunkts wiederherstellen

Sie können eine Tabelle aus Verlaufsdaten wiederherstellen, indem Sie die Verlaufsdaten in eine neue Tabelle kopieren. Das Kopieren von Verlaufsdaten funktioniert auch dann, wenn die Tabelle gelöscht wurde oder abgelaufen ist, sofern Sie die Tabelle innerhalb des Zeitreisefensters wiederherstellen.

Wenn Sie eine Tabelle aus Verlaufsdaten wiederherstellen, werden Tags aus der Quelltabelle nicht in die Zieltabelle kopiert. Informationen zur Tabellenpartitionierung werden ebenfalls nicht in die Zieltabelle kopiert. Wenn Sie das Partitionierungsschema der ursprünglichen Tabelle neu erstellen möchten, können Sie die ursprüngliche Anfrage zum Erstellen der Tabelle in Cloud Logging aufrufen und diese Informationen verwenden, um die wiederhergestellte Tabelle zu partitionieren.

Sie können eine Tabelle wiederherstellen, die gelöscht wurde, aber sich noch innerhalb des Zeitreisefensters befindet. Kopieren Sie dazu die Tabelle mit dem Zeit-Decorator @<time> in eine neue Tabelle. Sie können keine gelöschte Tabelle abfragen, auch wenn Sie einen Zeit-Decorator verwenden. Sie müssen es zuerst wiederherstellen.

Verwenden Sie die folgende Syntax mit dem Zeit-Decorator @<time>:

  • tableid@TIME, wobei TIME die Anzahl von Millisekunden seit der Unix-Epoche ist.
  • tableid@-TIME_OFFSET, wobei TIME_OFFSET das relative Offset von der aktuellen Zeit in Millisekunden ist.
  • tableid@0: gibt die ältesten verfügbaren Verlaufsdaten an.

Wählen Sie eine der folgenden Optionen aus, um eine Tabelle wiederherzustellen:

Console

Mit der Google Cloud Console können gelöschte Tabellen nicht wiederhergestellt werden.

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. Legen Sie zum Wiederherstellen der Tabelle zuerst einen UNIX-Zeitstempel in Millisekunden für die Zeit fest, in der die Tabelle existiert hat. Mit dem Linux-Befehl date können Sie den Unix-Zeitstempel aus einem regulären Zeitstempelwert generieren:

    date -d '2023-08-04 16:00:34.456789Z' +%s000
    
  3. Verwenden Sie dann den Befehl bq copy mit dem Zeitreise-Decorator @<time>, um den Tabellen-Kopiervorgang auszuführen.

    Geben Sie beispielsweise den folgenden Befehl ein, um die Tabelle mydataset.mytable zum Zeitpunkt 1418864998000 in die neue Tabelle mydataset.newtable zu kopieren.

    bq cp mydataset.mytable@1418864998000 mydataset.newtable
    

    Optional: Geben Sie das Flag --location an und legen Sie als Wert Ihren Standort fest.

    Sie können auch ein relatives Offset angeben. Im folgenden Beispiel wird die Version einer Tabelle von vor einer Stunde kopiert:

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

    Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Go in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Go API.

    Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

    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

    Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Java in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Java API.

    Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

    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

    Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Node.js in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Node.js API.

    Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

    // 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

    Bevor Sie dieses Beispiel anwenden, folgen Sie den Schritten zur Einrichtung von Python in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Python API.

    Richten Sie zur Authentifizierung bei BigQuery die Standardanmeldedaten für Anwendungen ein. Weitere Informationen finden Sie unter Authentifizierung für Clientbibliotheken einrichten.

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

Wenn Sie davon ausgehen, dass Sie eine Tabelle später wiederherstellen möchten, als dies durch das Zeitreisefenster zulässig ist, erstellen Sie einen Tabellen-Snapshot der Tabelle. Weitere Informationen finden Sie unter Einführung in Tabellen-Snapshots.

Sie können eine logische Ansicht nicht direkt wiederherstellen. Weitere Informationen finden Sie unter Ansicht wiederherstellen.

Nächste Schritte