Mengakses data historis

BigQuery memungkinkan Anda membuat kueri dan memulihkan data yang tersimpan di BigQuery yang telah diubah atau dihapus dalam periode perjalanan waktu Anda.

Membuat kueri data pada waktu tertentu

Anda dapat membuat kueri untuk data historis tabel dari waktu tertentu dalam periode perjalanan waktu menggunakan klausa FOR SYSTEM_TIME AS OF. Klausa ini menggunakan ekspresi stempel waktu konstanta dan mereferensikan versi tabel yang aktual pada stempel waktu tersebut. Tabel tersebut harus disimpan di BigQuery; tabel itu tidak bisa berupa tabel eksternal. Tidak ada batasan ukuran tabel saat menggunakan SYSTEM_TIME AS OF.

Misalnya, kueri berikut menampilkan versi historis tabel dari satu jam yang lalu:

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

Jika stempel waktu menentukan waktu dari sebelum periode waktu atau dari sebelum tabel dibuat, kueri akan gagal dan menampilkan error seperti berikut:

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

Setelah mengganti tabel yang ada menggunakan pernyataan CREATE OR REPLACE TABLE, Anda dapat menggunakan FOR SYSTEM_TIME AS OF untuk mengkueri tabel versi sebelumnya.

Jika tabel dihapus, kueri akan gagal dan menampilkan error seperti berikut:

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

Memulihkan tabel dari titik waktu

Anda dapat memulihkan tabel dari data historis dengan menyalin data historis ke dalam tabel baru. Menyalin data historis tetap berfungsi meskipun tabel telah dihapus atau telah habis masa berlakunya, asalkan Anda memulihkan tabel dalam durasi periode perjalanan waktu.

Saat Anda memulihkan tabel dari data historis, tag dari tabel sumber tidak disalin ke tabel tujuan. Informasi partisi tabel juga tidak disalin ke tabel tujuan. Untuk membuat ulang skema partisi tabel asli, Anda dapat melihat permintaan pembuatan tabel awal di Cloud Logging dan menggunakan informasi tersebut untuk memartisi tabel yang dipulihkan.

Anda dapat memulihkan tabel yang telah dihapus, tetapi masih dalam jangka waktu perjalanan dengan menyalin tabel tersebut ke tabel baru, menggunakan dekorator waktu @<time>. Anda tidak dapat membuat kueri tabel yang dihapus, meskipun Anda menggunakan dekorator waktu. Anda harus memulihkannya terlebih dahulu.

Gunakan sintaksis berikut dengan dekorator waktu @<time>:

  • tableid@TIME dengan TIME adalah jumlah milidetik sejak epoch Unix.
  • tableid@-TIME_OFFSET dengan TIME_OFFSET adalah offset relatif dari waktu saat ini, dalam milidetik.
  • tableid@0: Menentukan data historis terlama yang tersedia.

Untuk memulihkan tabel, pilih salah satu opsi berikut:

Konsol

Anda tidak dapat membatalkan penghapusan tabel menggunakan konsol Google Cloud .

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. Untuk memulihkan tabel, pertama-tama tentukan stempel waktu UNIX saat tabel ada (dalam milidetik). Anda dapat menggunakan perintah date Linux untuk membuat stempel waktu Unix dari nilai stempel waktu biasa:

    date -d '2023-08-04 16:00:34.456789Z' +%s000
    
  3. Kemudian, gunakan perintah bq copy dengan dekorator perjalanan waktu @<time> untuk melakukan operasi penyalinan tabel.

    Misalnya, masukkan perintah berikut untuk menyalin tabel mydataset.mytable pada saat 1418864998000 ke tabel baru mydataset.newtable.

    bq cp mydataset.mytable@1418864998000 mydataset.newtable
    

    (Opsional) Berikan flag --location dan tetapkan nilainya ke lokasi Anda.

    Anda juga dapat menentukan offset relatif. Contoh berikut menyalin versi tabel dari satu jam yang lalu:

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

    Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Go di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Go API.

    Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

    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

    Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Java di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Java API.

    Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

    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

    Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Node.js di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Node.js API.

    Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

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

    Sebelum mencoba contoh ini, ikuti petunjuk penyiapan Python di Panduan memulai BigQuery menggunakan library klien. Untuk mengetahui informasi selengkapnya, lihat Dokumentasi referensi BigQuery Python API.

    Untuk melakukan autentikasi ke BigQuery, siapkan Kredensial Default Aplikasi. Untuk mengetahui informasi selengkapnya, lihat Menyiapkan autentikasi untuk library klien.

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

Jika mengantisipasi bahwa Anda mungkin ingin memulihkan tabel lebih lama dari yang diizinkan oleh periode perjalanan waktu, buat snapshot tabel dari tabel tersebut. Untuk informasi selengkapnya, lihat Pengantar snapshot tabel.

Anda tidak dapat memulihkan tampilan logis secara langsung. Untuk mengetahui informasi selengkapnya, lihat Memulihkan tampilan.

Langkah berikutnya