Acceder al historial de datos

BigQuery te permite consultar y restaurar datos almacenados en BigQuery que se hayan modificado o eliminado en tu ventana de viaje en el tiempo.

Consultar datos en un momento concreto

Puedes consultar los datos históricos de una tabla desde cualquier momento del periodo de viaje en el tiempo mediante una cláusula FOR SYSTEM_TIME AS OF. Esta cláusula toma una expresión de marca de tiempo constante y hace referencia a la versión de la tabla que estaba vigente en esa marca de tiempo. La tabla debe estar almacenada en BigQuery. No puede ser una tabla externa. No hay límite en el tamaño de las tablas cuando se usa SYSTEM_TIME AS OF.

Por ejemplo, la siguiente consulta devuelve una versión histórica de la tabla de hace una hora:

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

Si la marca de tiempo especifica una hora anterior al periodo de viaje en el tiempo o a la creación de la tabla, la consulta fallará y devolverá un error como el siguiente:

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

Después de sustituir una tabla con la declaración CREATE OR REPLACE TABLE, puedes usar FOR SYSTEM_TIME AS OF para consultar la versión anterior de la tabla.

Si se ha eliminado la tabla, la consulta fallará y devolverá un error como el siguiente:

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

Restaurar una tabla a partir de un momento dado

Puedes restaurar una tabla a partir de datos históricos copiando los datos históricos en una tabla nueva. La copia de datos históricos funciona aunque la tabla se haya eliminado o haya caducado, siempre que la restaure durante el periodo de la ventana de viaje en el tiempo.

Cuando restauras una tabla a partir de datos históricos, las etiquetas de la tabla de origen no se copian en la tabla de destino. La información de partición de la tabla tampoco se copia en la tabla de destino. Para recrear el esquema de partición de la tabla original, puedes ver la solicitud de creación de la tabla inicial en Cloud Logging y usar esa información para crear particiones en la tabla restaurada.

Puedes restaurar una tabla que se haya eliminado, pero que aún esté dentro del periodo de la función de viaje en el tiempo, copiándola en una tabla nueva con el decorador de tiempo @<time>. No puedes consultar una tabla eliminada, aunque uses un decorador de tiempo. Primero debes restaurarlo.

Usa la siguiente sintaxis con el decorador de tiempo @<time>:

  • tableid@TIME, donde TIME es el número de milisegundos transcurridos desde el inicio del registro de tiempo Unix.
  • tableid@-TIME_OFFSET, donde TIME_OFFSET es el desplazamiento relativo desde la hora actual, en milisegundos.
  • tableid@0: especifica los datos históricos más antiguos disponibles.

Para restaurar una tabla, selecciona una de las siguientes opciones:

Consola

No puedes restaurar una tabla eliminada con la Google Cloud consola.

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. Para restaurar una tabla, primero debes determinar la marca de tiempo UNIX de cuándo existía la tabla (en milisegundos). Puedes usar el comando date de Linux para generar la marca de tiempo de Unix a partir de un valor de marca de tiempo normal:

    date -d '2023-08-04 16:00:34.456789Z' +%s000
    
  3. A continuación, usa el comando bq copy con el decorador de viaje en el tiempo @<time> para copiar la tabla.

    Por ejemplo, introduce el siguiente comando para copiar la tabla mydataset.mytable en el momento 1418864998000 en una tabla nueva mydataset.newtable.

    bq cp mydataset.mytable@1418864998000 mydataset.newtable
    

    (Opcional) Proporcione la marca --location y asigne el valor a su ubicación.

    También puedes especificar una variación relativa. En el siguiente ejemplo se copia la versión de una tabla de hace una hora:

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

    Antes de probar este ejemplo, sigue las Goinstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Go de BigQuery.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

    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

    Antes de probar este ejemplo, sigue las Javainstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Java de BigQuery.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

    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

    Antes de probar este ejemplo, sigue las Node.jsinstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Node.js de BigQuery.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

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

    Antes de probar este ejemplo, sigue las Pythoninstrucciones de configuración de la guía de inicio rápido de BigQuery con bibliotecas de cliente. Para obtener más información, consulta la documentación de referencia de la API Python de BigQuery.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Para obtener más información, consulta el artículo Configurar la autenticación para bibliotecas de cliente.

    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 prevé que puede que quiera restaurar una tabla más adelante de lo que permite el periodo de viaje en el tiempo, cree una instantánea de la tabla. Para obtener más información, consulta el artículo Introducción a las capturas de tablas.

No puedes restaurar una vista lógica directamente. Para obtener más información, consulta Restaurar una vista.

Siguientes pasos