Restablece tablas borradas

En este documento, se describe cómo restablecer (o recuperar) una tabla borrada en BigQuery. Puedes restablecer una tabla borrada dentro del período de viaje en el tiempo especificado para el conjunto de datos, incluidas las eliminaciones explícitas y las implícitas debidas al vencimiento de la tabla. También puedes configurar el período de viaje en el tiempo.

Para obtener información sobre cómo restablecer un conjunto de datos o una instantánea borrados por completo, consulta los siguientes recursos:

El período de viaje en el tiempo puede tener una duración de dos a siete días. Después de que transcurre el período de viaje en el tiempo, BigQuery proporciona un período de seguridad ante fallas en el que los datos borrados se conservan automáticamente durante siete días más. Una vez que transcurre el período de seguridad, no es posible restablecer una tabla con ningún método, incluida la apertura de un ticket de asistencia.

Antes de comenzar

Asegúrate de tener los permisos de Identity and Access Management (IAM) necesarios para restablecer una tabla borrada.

Roles obligatorios

Para obtener los permisos que necesitas para restablecer una tabla borrada, pídele a tu administrador que te otorgue el rol de IAM de usuario de BigQuery (roles/bigquery.user) en el proyecto. Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

También puedes obtener los permisos necesarios a través de roles personalizados o cualquier otro rol predefinido.

Cómo restablecer una tabla

Para restablecer una tabla desde los datos históricos, puedes copiar los datos históricos en una tabla nueva. La copia de datos históricos funciona incluso si la tabla se borró o caducó, siempre que restablezcas la tabla dentro de la duración del período de viaje en el tiempo.

Cuando restableces 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 volver a crear 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 particionar la tabla restaurada.

Puedes restablecer una tabla que se haya borrado, pero que aún se encuentre dentro del período. Para ello, copia la tabla en una tabla nueva con el decorador de tiempo @<time>. No puedes consultar una tabla borrada, incluso si usas un decorador de tiempo. Primero debes restablecerlo.

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

  • tableid@TIME en el que TIME es la cantidad de milisegundos transcurridos desde la época UNIX.
  • tableid@-TIME_OFFSET en el que TIME_OFFSET es la compensación relativa desde la hora actual, en milisegundos.
  • tableid@0: Especifica los datos históricos más antiguos disponibles.

Para restablecer una tabla, elige una de las siguientes opciones:

Console

No puedes recuperar una tabla 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 restablecer una tabla, primero determina una marca de tiempo UNIX de cuando existió 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. Luego, usa el comando bq copy con el decorador de viajes en el tiempo @<time> para realizar la operación de copia de tabla.

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

    bq cp mydataset.mytable@1418864998000 mydataset.newtable
    

    Opcional: Proporciona la marca --location y configura el valor en tu ubicación.

    También puedes especificar un desplazamiento relativo. En el siguiente ejemplo, se copia la versión de una tabla de hace una hora atrás:

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

    Antes de probar este ejemplo, sigue las instrucciones de configuración para Go incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Go.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas 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 instrucciones de configuración para Java incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Java.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas 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 instrucciones de configuración para Node.js incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Node.js.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas 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 instrucciones de configuración para Python incluidas en la guía de inicio rápido de BigQuery sobre cómo usar bibliotecas cliente. Para obtener más información, consulta la documentación de referencia de la API de BigQuery para Python.

    Para autenticarte en BigQuery, configura las credenciales predeterminadas de la aplicación. Si deseas obtener más información, consulta Configura la autenticación para bibliotecas 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és que quieres restablecer una tabla más tarde de lo que permite el período de viaje en el tiempo, crea una instantánea de la tabla. Para obtener más información, consulta Introducción a las instantáneas de tablas.

No puedes restablecer una vista lógica directamente. Para obtener más información, consulta Cómo restablecer una vista.

Soluciona problemas de recuperación de tablas

Cómo consultar la tabla borrada con una marca de tiempo anterior

No puedes restablecer los datos de una tabla consultando una tabla borrada en el pasado con un decorador de marca de tiempo ni usando FOR SYSTEM_TIME AS OF para guardar el resultado en una tabla de destino. Si usas cualquiera de estos métodos, se genera el siguiente error:

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

En su lugar, para copiar la tabla, sigue los pasos que se indican en Cómo restablecer una tabla.

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

Cuando intentes ejecutar el comando de copia desde Google Cloud Shell, es posible que encuentres un error como el siguiente:

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

No se admite el uso de Cloud Shell desde la consola con los Controles del servicio de VPC, ya que se trata como una solicitud fuera de los perímetros de servicio y se rechaza el acceso a los datos que protegen los Controles del servicio de VPC. Google Cloud Para solucionar este problema, inicia y conéctate a Cloud Shell de forma local con Google Cloud CLI.

Error: Latest categories are incompatible with schema

Si ejecutas el comando de copia desde Google Cloud Shell, es posible que recibas un error como el siguiente:

Latest categories are incompatible with schema at TIMESTAMP

Este error puede deberse a varios motivos:

Para resolver este error, haz lo siguiente:

  1. Asegúrate de que el esquema de la tabla de destino sea idéntico y de que no falte ninguna de las columnas de la tabla original en la tabla de destino.
  2. Quita las etiquetas de política a nivel de la columna de la tabla de destino que no estén en el esquema de la tabla original.

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

Si ejecutas el comando bq copy desde Google Cloud Shell, es posible que recibas un error como el siguiente:

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

Este error indica que intentas recuperar datos del estado de la tabla anterior al período de viaje en el tiempo o antes de que se creara la tabla. Esta opción no es compatible. El mensaje de error contiene la marca de tiempo más reciente que se puede usar para leer los datos de la tabla. Usa la marca de tiempo del error en el comando bq copy.

Este error también puede ocurrir cuando proporcionas un valor de marca de tiempo negativo, por ejemplo, TABLE@-1744963620000. En su lugar, usa un desplazamiento de tiempo que se pueda usar con el signo -.

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

Este mensaje de error indica que el comando bq cp contiene un valor de marca de tiempo negativo como desplazamiento y que intentaste leer la tabla en CURRENT_TIMESTAMP - PROVIDED TIMESTAMP. Por lo general, este valor es una marca de tiempo de 1970. Para solucionar este problema, verifica los valores de desplazamiento o de marca de tiempo cuando establezcas el valor del decorador de tabla y usa el signo - de forma adecuada.

¿Qué sigue?