Gelöschte Tabellen wiederherstellen

In diesem Dokument wird beschrieben, wie Sie eine gelöschte Tabelle in BigQuery wiederherstellen (oder wiederherstellen). Sie können eine gelöschte Tabelle innerhalb des für das Dataset angegebenen Zeitreisefensters wiederherstellen, einschließlich expliziter und impliziter Löschungen aufgrund des Ablaufs einer Tabelle. Sie können auch das Zeitreisefenster konfigurieren.

Informationen zum Wiederherstellen eines gesamten gelöschten Datasets oder Snapshots finden Sie in den folgenden Ressourcen:

Das Zeitreisefenster kann zwischen zwei und sieben Tagen liegen. Nach Ablauf des Zeitreisefensters bietet BigQuery eine Fail-Safe-Periode in der die gelöschten Daten automatisch sieben weitere Tage aufbewahrt werden. Nach Ablauf der Fail-Safe-Periode ist es nicht mehr möglich, eine Tabelle wiederherzustellen, weder durch das Öffnen eines Support-Tickets noch durch andere Methoden.

Hinweis

Prüfen Sie, ob Sie die erforderlichen IAM-Berechtigungen (Identity and Access Management) zum Wiederherstellen einer gelöschten Tabelle haben.

Erforderliche Rollen

Bitten Sie Ihren Administrator, Ihnen die IAM-Rolle „BigQuery-Nutzer (roles/bigquery.user)“ für das Projekt zu gewähren, um die erforderlichen Berechtigungen zum Wiederherstellen einer gelöschten Tabelle zu erhalten. Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

Tabelle 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, Tags aus der Quelltabelle nicht in die Zieltabelle kopiert werden. 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 @<time> Zeit-Decorator in eine neue Tabelle. Sie können eine gelöschte Tabelle nicht abfragen, auch wenn Sie einen Zeit-Decorator verwenden. Sie müssen sie zuerst wiederherstellen.

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

  • 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

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

bq

  1. Aktivieren Sie Cloud Shell in der Google Cloud Console.

    Cloud Shell aktivieren

    Unten in der Google Cloud Console wird eine Cloud Shell Sitzung gestartet und eine Befehlszeilenaufforderung angezeigt. Cloud Shell ist eine Shell-Umgebung in der das Google Cloud CLI bereits installiert ist und Werte für Ihr aktuelles Projekt bereits festgelegt sind. Das Initialisieren der Sitzung kann einige Sekunden dauern.

  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 bq copy Befehl mit dem @<time> Zeitreise-Decorator, um den Tabellenkopier-Vorgang 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
    

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.

Zeitpunkt des Löschens einer Tabelle ermitteln

Verwenden Sie den folgenden Filter im Log-Explorer in der Google Cloud Console, um den Audit-Eintrag zu ermitteln, der den Ablauf oder das Löschen einer bestimmten Tabelle zeigt:

resource.type="bigquery_resource"
protoPayload.resourceName="projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_ID"
(protoPayload.methodName="google.cloud.bigquery.v2.TableService.DeleteTable" OR protoPayload.methodName="tableservice.delete" OR protoPayload.serviceData.jobCompletedEvent.job.jobConfiguration.query.statementType="DROP_TABLE" OR protoPayload.methodName="InternalTableExpired")

Ersetzen Sie Folgendes:

  • PROJECT_ID: Ihre Projekt-ID.
  • DATASET_ID: die ID des Datasets, das die Tabelle enthielt.
  • TABLE_ID: die ID der gelöschten Tabelle.

Alternativ können Sie den folgenden Filter verwenden, um den Ablauf oder das Löschen des Datasets zu finden, das die Tabelle enthielt:

resource.type="bigquery_dataset"
protoPayload.resourceName="projects/PROJECT_ID/datasets/DATASET_ID"
(protoPayload.methodName="google.cloud.bigquery.v2.DatasetService.DeleteDataset" OR protoPayload.methodName="datasetservice.delete")

Ersetzen Sie Folgendes:

  • PROJECT_ID: Ihre Projekt-ID.
  • DATASET_ID: die ID des Datasets, das die Tabelle enthielt.

Ursache für das Löschen der Tabelle ermitteln

Mit der INFORMATION_SCHEMA.TABLE_STORAGE Ansicht können Sie ermitteln, wie eine Tabelle gelöscht wurde.

Die Ansicht INFORMATION_SCHEMA.TABLE_STORAGE enthält Informationen zu aktuellen Tabellen und Tabellen, die innerhalb des Zeitreisefensters gelöscht wurden. Wenn eine Tabelle gelöscht wurde, enthält die Spalte table_deletion_time den Zeitstempel für das Löschen und die Spalte table_deletion_reason die Löschmethode.

So ermitteln Sie den Grund für das Löschen einer Tabelle:INFORMATION_SCHEMA.TABLE_STORAGE

SELECT
  table_name,
  deleted,
  table_deletion_time,
  table_deletion_reason
FROM
  `PROJECT_ID`.`region-REGION`.INFORMATION_SCHEMA.TABLE_STORAGE
WHERE
  table_schema = "DATASET_ID"
  AND table_name = "TABLE_ID"

Ersetzen Sie die folgenden Variablen:

  • PROJECT_ID: Ihre Projekt-ID.
  • REGION: die Region des Datasets, das die Tabelle enthielt.
  • DATASET_ID: die ID des Datasets, das die Tabelle enthielt.
  • TABLE_ID: die ID der gelöschten Tabelle.

In der Spalte table_deletion_reason wird der Grund für das Löschen der Tabelle erläutert:

  • TABLE_EXPIRATION: Die Tabelle wurde nach Ablauf der festgelegten Ablaufzeit gelöscht.
  • DATASET_DELETION: Das Dataset, zu dem die Tabelle gehörte, wurde von einem Nutzer gelöscht.
  • USER_DELETED: Die Tabelle wurde von einem Nutzer gelöscht.

Fehlerbehebung bei der Wiederherstellung von Tabellen

Abfragen der gelöschten Tabelle mit einem Zeitstempel in der Vergangenheit

Sie können Tabellendaten nicht wiederherstellen, indem Sie eine gelöschte Tabelle in der Vergangenheit mit einem Zeitstempel-Decorator abfragen oder indem Sie FOR SYSTEM_TIME AS OF verwenden, um das Ergebnis in einer Zieltabelle zu speichern. Bei Verwendung einer dieser Methoden wird der folgende Fehler generiert:

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

Folgen Sie stattdessen der Anleitung unter Tabelle wiederherstellen, um die Tabelle zu kopieren.

Fehler: VPC Service Controls: Request is prohibited by organization's policy

Wenn Sie versuchen, den Kopierbefehl über Google Cloud Shell auszuführen, kann ein Fehler wie der folgende auftreten:

BigQuery error in cp operation: VPC Service Controls: Request is prohibited by organization's policy

Die Verwendung von Cloud Shell über die Google Cloud Console mit VPC SC wird nicht unterstützt, da sie als Anfrage außerhalb der Dienstperimeter behandelt wird und der Zugriff auf Daten, die durch VPC Service Controls geschützt werden, verweigert wird. Um dieses Problem zu umgehen, starten Sie Cloud Shell lokal und stellen Sie eine Google Cloud CLI her.

Fehler: Latest categories are incompatible with schema

Wenn Sie den Kopierbefehl über Google Cloud Shell ausführen, kann ein Fehler wie der folgende auftreten:

Latest categories are incompatible with schema at TIMESTAMP

Für diesen Fehler gibt es mehrere mögliche Ursachen:

So beheben Sie diesen Fehler:

  1. Achten Sie darauf, dass das Schema der Zieltabelle identisch ist und dass keine Spalten der ursprünglichen Tabelle in der Zieltabelle fehlen.
  2. Entfernen Sie alle Richtlinien-Tags auf Spaltenebene aus der Zieltabelle, die nicht im Schema der ursprünglichen Tabelle enthalten sind.

Fehler: BigQuery error in cp operation: Invalid time travel timestamp

Wenn Sie den Befehl bq copy über Google Cloud Shell ausführen, kann ein Fehler wie der folgende auftreten:

BigQuery error in cp operation: Invalid time travel timestamp 1744343690000 for
table PROJECT_ID:DATASET_ID.TABLE_ID@1744343690000.
Cannot read before 1744843691075

Dieser Fehler weist darauf hin, dass Sie versuchen, Daten aus dem Tabellenstatus vor dem Zeitreisefenster oder vor dem Erstellen der Tabelle wiederherzustellen. Dies wird nicht unterstützt. Die Fehlermeldung enthält den letzten Zeitstempel, der zum Lesen der Tabellendaten verwendet werden kann. Verwenden Sie den Zeitstempel im Fehler im Befehl bq copy.

Dieser Fehler kann auch auftreten, wenn Sie einen negativen Zeitstempelwert angeben, z. B. TABLE@-1744963620000. Verwenden Sie stattdessen ein Zeit-Offset, das mit dem Zeichen - verwendet werden kann.

BigQuery error in cp operation: Invalid time travel timestamp 584878816 for
table PROJECT_ID:DATASET_ID.TABLE_ID@584878816.
Cannot read before 1744843691075

Diese Fehlermeldung weist darauf hin, dass der Befehl bq cp einen negativen Zeitstempelwert als Offset enthält und dass Sie versucht haben, die Tabelle unter CURRENT_TIMESTAMP - PROVIDED TIMESTAMP zu lesen. Dieser Wert ist normalerweise ein Zeitstempel im Jahr 1970. Um dieses Problem zu umgehen, prüfen Sie die Offset- oder Zeitstempelwerte, wenn Sie den Tabellen-Decorator-Wert festlegen, und verwenden Sie das Zeichen - entsprechend.

Materialisierte Ansichten

Sie können eine gelöschte materialisierte Ansicht nicht direkt wiederherstellen. Wenn Sie eine materialisierte Ansicht löschen, müssen Sie sie neu erstellen.

Wenn Sie eine Tabelle löschen, die eine Basistabelle für eine materialisierte Ansicht ist, kann die materialisierte Ansicht nicht mehr abgefragt oder aktualisiert werden. Wenn Sie die Basistabelle wiederherstellen, indem Sie der Anleitung unter Tabelle wiederherstellenfolgen, müssen Sie auch alle materialisierten Ansichten neu erstellen , die diese Tabelle verwenden.

Externe Tabellen

Sie können eine gelöschte externe Tabelle nicht direkt wiederherstellen. Wenn Sie eine externe Tabelle löschen, müssen Sie sie neu erstellen. Für die Neuerstellung ist die Definition der ursprünglichen Tabelle erforderlich, insbesondere die folgenden:

  • Das Schema der Tabelle
  • Die Quell-URIs, die auf die externen Daten verweisen
  • Das Format der externen Daten

Sie können diese Informationen aus Cloud Logging abrufen, indem Sie nach dem Logeintrag zum Erstellen der Tabelle suchen. Sie können auch versuchen, die URIs abzurufen, indem Sie die INFORMATION_SCHEMA.TABLE_OPTIONS Ansicht abfragen, wenn die Tabelle gerade gelöscht wurde.

Durch das Löschen der externen Tabelle werden die zugrunde liegenden Daten nicht gelöscht.

Nächste Schritte