Accéder aux données de l'historique

BigQuery vous permet d'interroger et de restaurer les données stockées dans BigQuery qui ont été modifiées ou supprimées au cours de votre période de fonctionnalité temporelle.

Interroger les données à un moment précis

Vous pouvez interroger les données historiques d'une table à tout moment dans la fenêtre temporelle en utilisant une clause FOR SYSTEM_TIME AS OF. Cette clause prend une expression d'horodatage constante et fait référence à la version de la table active à cet horodatage. La table doit être stockée dans BigQuery. Il ne peut pas s'agir d'une table externe. Lorsque vous utilisez SYSTEM_TIME AS OF, la taille de la table n'est pas limitée.

Par exemple, la requête suivante renvoie une version historique de la table d'une heure écoulée :

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

Si l'horodatage spécifie une heure antérieure à la fenêtre de fonctionnalité temporelle ou avant la création de la table, la requête échoue et renvoie une erreur semblable à celle-ci :

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

Après avoir remplacé une table existante à l'aide de l'instruction CREATE OR REPLACE TABLE, vous pouvez utiliser FOR SYSTEM_TIME AS OF pour interroger la version précédente de la table.

Si la table a été supprimée, la requête échoue et renvoie une erreur semblable à celle-ci :

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

Restaurer une table à partir d'un moment précis

Vous pouvez restaurer une table à partir des données de l'historique en copiant les données de l'historique dans une nouvelle table. La copie des données historiques fonctionne même si la table a été supprimée ou a expiré, tant que vous la restaurez pendant la durée de la fenêtre de fonctionnalité temporelle.

Lorsque vous restaurez une table à partir de données historiques, les tags de la table source ne sont pas copiés dans la table de destination. Les informations de partitionnement de la table ne sont pas non plus copiées dans la table de destination. Pour recréer le schéma de partitionnement de la table d'origine, vous pouvez consulter la demande de création de table initiale dans Cloud Logging et utiliser ces informations pour partitionner la table restaurée.

Vous pouvez restaurer une table supprimée, mais toujours dans la fenêtre temporelle, en copiant la table dans une nouvelle table, à l'aide du décorateur d'heure @<time>. Vous ne pouvez pas interroger une table supprimée, même si vous utilisez un décorateur d'heure. Vous devez d'abord le restaurer.

Utilisez la syntaxe suivante avec le décorateur de temps @<time> :

  • tableid@TIME, où TIME est le nombre de millisecondes écoulées depuis l'époque Unix.
  • tableid@-TIME_OFFSET, où TIME_OFFSET est le décalage relatif par rapport à l'heure actuelle, en millisecondes.
  • tableid@0 : spécifie les données de l'historique les plus anciennes disponibles.

Pour restaurer une table, sélectionnez l'une des options suivantes :

Console

Vous ne pouvez pas annuler la suppression d'une table à l'aide de la console Cloud de Confiance .

bq

  1. In the Cloud de Confiance console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Cloud de Confiance 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. Pour restaurer une table, commencez par déterminer un horodatage UNIX (en millisecondes) correspondant à la période d'existence de la table. Vous pouvez utiliser la commande Linux date pour générer l'horodatage Unix à partir d'une valeur d'horodatage standard :

    date -d '2023-08-04 16:00:34.456789Z' +%s000
    
  3. Exécutez ensuite la commande bq copy avec le décorateur de fonctionnalité temporelle @<time> pour effectuer l'opération de copie de table.

    Par exemple, saisissez la commande suivante pour copier la table mydataset.mytable au moment 1418864998000 dans une nouvelle table mydataset.newtable.

    bq cp mydataset.mytable@1418864998000 mydataset.newtable
    

    (Facultatif) Spécifiez l'option --location et définissez la valeur correspondant à votre emplacement.

    Vous pouvez également spécifier un décalage relatif. L'exemple suivant copie la version d'une table d'il y a une heure :

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

    Avant d'essayer cet exemple, suivez les instructions de configuration pour Go du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Go.

    Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

    Avant d'exécuter des exemples de code, définissez la variable d'environnement GOOGLE_CLOUD_UNIVERSE_DOMAIN sur s3nsapis.fr.

    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

    Avant d'essayer cet exemple, suivez les instructions de configuration pour Java du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Java.

    Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

    Avant d'exécuter des exemples de code, définissez la variable d'environnement GOOGLE_CLOUD_UNIVERSE_DOMAIN sur s3nsapis.fr.

    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

    Avant d'essayer cet exemple, suivez les instructions de configuration pour Node.js du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Node.js.

    Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

    Avant d'exécuter des exemples de code, définissez la variable d'environnement GOOGLE_CLOUD_UNIVERSE_DOMAIN sur s3nsapis.fr.

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

    Avant d'essayer cet exemple, suivez les instructions de configuration pour Python du guide de démarrage rapide de BigQuery : Utiliser les bibliothèques clientes. Pour en savoir plus, consultez la documentation de référence de l'API BigQuery pour Python.

    Pour vous authentifier auprès de BigQuery, configurez le service Identifiants par défaut de l'application. Pour en savoir plus, consultez la page Configurer l'authentification pour les bibliothèques clientes.

    Avant d'exécuter des exemples de code, définissez la variable d'environnement GOOGLE_CLOUD_UNIVERSE_DOMAIN sur s3nsapis.fr.

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

Si vous prévoyez de restaurer une table ultérieurement à ce qui est autorisé par la fenêtre temporelle, créez un instantané de la table. Pour en savoir plus, consultez la page Présentation des instantanés de table.

Vous ne pouvez pas restaurer directement une vue logique. Pour en savoir plus, consultez Restaurer une vue.

Étapes suivantes