Mengelola retensi data dengan TTL

Halaman ini membahas cara menggunakan time to live (TTL) di tabel Spanner. Untuk mempelajari lebih lanjut, lihat Tentang TTL.

Sebelum memulai

Sebelum memulai, ikuti praktik terbaik berikut.

Mengaktifkan pencadangan dan pemulihan point-in-time

Sebelum menambahkan TTL ke tabel, sebaiknya aktifkan pencadangan dan pemulihan Spanner. Hal ini memungkinkan Anda memulihkan database sepenuhnya jika tidak sengaja menghapus data dengan kebijakan TTL.

Jika telah mengaktifkan pemulihan titik waktu, Anda dapat melihat dan memulihkan data yang dihapus—tanpa pemulihan penuh dari cadangan—jika data tersebut berada dalam periode retensi versi yang dikonfigurasi. Untuk mengetahui informasi tentang membaca data sebelumnya, lihat Melakukan pembacaan yang sudah tidak berlaku.

Membersihkan data lama

Jika ini adalah pertama kalinya Anda menggunakan TTL dan Anda mengharapkan operasi pertama untuk menghapus banyak baris, sebaiknya bersihkan data lama secara manual terlebih dahulu menggunakan DML yang dipartisi. Hal ini memberi Anda kontrol lebih besar atas penggunaan resource, bukan menyerahkannya ke proses latar belakang TTL. TTL berjalan dengan prioritas rendah, ideal untuk pembersihan inkremental. Namun, hal ini kemungkinan akan memperpanjang waktu yang diperlukan untuk menghapus kumpulan baris awal dalam database yang sibuk karena penjadwal tugas internal Spanner akan memprioritaskan tugas lain, seperti kueri pengguna.

Memverifikasi kondisi Anda

Untuk tabel GoogleSQL, jika ingin memverifikasi data yang akan terpengaruh oleh kebijakan penghapusan baris sebelum mengaktifkan TTL, Anda dapat membuat kueri tabel menggunakan kondisi yang sama. Contoh:

GoogleSQL

  SELECT COUNT(*)
  FROM CalculatedRoutes
  WHERE TIMESTAMP_ADD(CreatedAt, INTERVAL 30 DAY) < CURRENT_TIMESTAMP();

Izin yang diperlukan

Untuk mengubah skema database, Anda harus memiliki izin spanner.databases.updateDdl. Untuk mengetahui detailnya, lihat Kontrol akses untuk Spanner.

Membuat kebijakan penghapusan baris

GoogleSQL

Untuk membuat kebijakan penghapusan baris menggunakan GoogleSQL, Anda dapat menentukan klausa ROW DELETION POLICY saat membuat tabel baru, atau menambahkan kebijakan ke tabel yang ada. Klausa ini berisi ekspresi kolom dan interval.

Untuk menambahkan kebijakan pada saat pembuatan tabel:

CREATE TABLE MyTable(
Key INT64,
CreatedAt TIMESTAMP,
) PRIMARY KEY (Key),
ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

Dengan keterangan:

  • timestamp_column harus berupa kolom yang ada dengan jenis TIMESTAMP. Kolom dengan stempel waktu commit valid, begitu juga kolom yang dihasilkan. Namun, Anda tidak dapat menentukan kolom yang dihasilkan yang mereferensikan kolom stempel waktu commit.

  • num_days adalah jumlah hari setelah stempel waktu di timestamp_column tempat baris ditandai untuk penghapusan. Nilainya harus berupa bilangan bulat non-negatif dan DAY adalah satu-satunya unit yang didukung.

Untuk menambahkan kebijakan ke tabel yang ada, gunakan pernyataan ALTER TABLE. Tabel dapat memiliki maksimal satu kebijakan penghapusan baris. Menambahkan kebijakan penghapusan baris ke tabel dengan kebijakan yang ada akan gagal dengan error. Lihat TTL pada kolom yang dihasilkan untuk menentukan logika penghapusan baris yang lebih canggih.

ALTER TABLE Albums
ADD ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

PostgreSQL

Untuk membuat kebijakan penghapusan baris menggunakan PostgreSQL, Anda dapat menentukan klausa TTL INTERVAL saat membuat tabel baru, atau menambahkan kebijakan ke tabel yang ada.

Untuk menambahkan kebijakan pada saat pembuatan tabel:

CREATE TABLE mytable (
  key bigint NOT NULL,
  timestamp_column_name TIMESTAMPTZ,
  PRIMARY KEY(key)
) TTL INTERVAL interval_spec ON timestamp_column_name;

Dengan keterangan:

  • timestamp_column_name harus berupa kolom dengan jenis data TIMESTAMPTZ. Anda perlu membuat kolom ini dalam pernyataan CREATE TABLE. Kolom dengan stempel waktu commit valid, begitu juga kolom yang dihasilkan. Namun, Anda tidak dapat menentukan kolom yang dihasilkan yang mereferensikan kolom stempel waktu commit.

  • interval_spec adalah jumlah hari setelah stempel waktu di timestamp_column_name tempat baris ditandai untuk penghapusan. Nilainya harus berupa bilangan bulat positif dan harus dievaluasi ke bilangan bulat hari. Misalnya, '3 days' diizinkan, tetapi '3 days - 2 minutes' menampilkan error.

Untuk menambahkan kebijakan ke tabel yang ada, gunakan pernyataan ALTER TABLE. Tabel dapat memiliki maksimal satu kebijakan TTL. Menambahkan kebijakan TTL ke tabel dengan kebijakan yang ada akan gagal dengan error. Lihat TTL pada kolom yang dihasilkan untuk menentukan logika TTL yang lebih rumit.

Untuk menambahkan kebijakan ke tabel yang ada:

ALTER TABLE albums
ADD COLUMN timestampcolumn TIMESTAMPTZ;

ALTER TABLE albums
ADD TTL INTERVAL '5 days' ON timestampcolumn;

Pembatasan

Kebijakan penghapusan baris memiliki batasan berikut.

TTL pada tabel yang dirujuk oleh kunci asing

Anda tidak dapat membuat kebijakan penghapusan baris:

  • Pada tabel yang direferensikan oleh kunci asing yang tidak menyertakan batasan ON DELETE CASCADE.
  • Pada induk tabel yang dirujuk oleh kunci asing yang tidak menyertakan tindakan referensi ON DELETE CASCADE.

Pada contoh berikut, Anda tidak dapat menambahkan kebijakan penghapusan baris ke tabel Customers, karena direferensikan oleh kunci asing dalam tabel Orders, yang tidak memiliki batasan ON DELETE CASCADE. Menghapus pelanggan dapat melanggar batasan kunci asing ini. Anda juga tidak dapat menambahkan kebijakan penghapusan baris ke tabel Districts. Menghapus baris dari Districts dapat menyebabkan penghapusan secara berantai di tabel Customers turunan, yang dapat melanggar batasan kunci asing pada tabel Orders.

GoogleSQL

CREATE TABLE Districts (
  DistrictID INT64
) PRIMARY KEY (DistrictID);

CREATE TABLE Customers (
  DistrictID INT64,
  CustomerID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID, CustomerID),
INTERLEAVE IN PARENT Districts ON DELETE CASCADE;

CREATE TABLE Orders (
  OrderID INT64,
  DistrictID INT64,
  CustomerID INT64,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (DistrictID, CustomerID) REFERENCES Customers (DistrictID, CustomerID)
) PRIMARY KEY (OrderID);

PostgreSQL

CREATE TABLE districts (
  districtid   bigint NOT NULL,
  PRIMARY KEY(districtid)
);

CREATE TABLE customers (
  districtid   bigint NOT NULL,
  customerid   bigint NOT NULL,
  createdat  timestamptz,
  PRIMARY KEY(districtid, customerid)
) INTERLEAVE IN PARENT districts ON DELETE CASCADE;

CREATE TABLE orders (
  orderid bigint NOT NULL,
  districtid   bigint,
  customerid bigint,
  PRIMARY KEY(orderid),
  CONSTRAINT fk_customerorder FOREIGN KEY (districtid, customerid) REFERENCES customers (districtid, customerid)
);

Anda dapat membuat kebijakan penghapusan baris pada tabel yang direferensikan oleh batasan kunci asing yang menggunakan ON DELETE CASCADE. Pada contoh berikut, Anda dapat membuat kebijakan penghapusan baris di tabel Customers yang dirujuk oleh batasan kunci asing CustomerOrder, yang ditentukan di tabel Orders. Saat TTL menghapus baris di Customers, penghapusan akan beruntun ke baris yang cocok yang ada di tabel Orders.

GoogleSQL

 CREATE TABLE Districts (
  DistrictID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID),
ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));

CREATE TABLE Customers (
  DistrictID INT64,
  CustomerID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (DistrictID, CustomerID),
INTERLEAVE IN PARENT Districts ON DELETE CASCADE,
ROW DELETION POLICY (OLDER_THAN(CreatedAt, INTERVAL 1 DAY));

CREATE TABLE Orders (
  OrderID INT64,
  DistrictID INT64,
  CustomerID INT64,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (DistrictID, CustomerID) REFERENCES Customers (DistrictID, CustomerID) ON DELETE CASCADE
) PRIMARY KEY (OrderID);

PostgreSQL

CREATE TABLE districts (
  districtid   bigint NOT NULL,
  createdat  timestamptz,
  PRIMARY KEY(districtid)
) TTL INTERVAL '1 day' ON createdat;

CREATE TABLE customers (
  districtid   bigint NOT NULL,
  customerid   bigint NOT NULL,
  createdat  timestamptz,
  PRIMARY KEY(districtid, customerid)
) INTERLEAVE IN PARENT districts ON DELETE CASCADE
TTL INTERVAL '1 day' ON createdat;

CREATE TABLE orders (
  orderid bigint NOT NULL,
  districtid bigint,
  customerid bigint,
  PRIMARY KEY(orderid),
  CONSTRAINT fk_customerorder FOREIGN KEY (districtid, customerid) REFERENCES customers (districtid, customerid) ON DELETE CASCADE
);

Demikian pula, Anda dapat membuat kebijakan penghapusan baris pada induk tabel yang direferensikan oleh batasan kunci asing ON DELETE CASCADE.

TTL pada kolom dengan nilai default

Kebijakan penghapusan baris dapat menggunakan kolom stempel waktu dengan nilai default. Nilai default biasanya adalah CURRENT_TIMESTAMP. Jika tidak ada nilai yang ditetapkan secara eksplisit ke kolom, atau jika kolom ditetapkan ke nilai defaultnya oleh pernyataan INSERT atau UPDATE, nilai default akan digunakan dalam penghitungan aturan.

Dalam contoh berikut, nilai default untuk kolom CreatedAt dalam tabel Customers adalah stempel waktu saat baris dibuat.

GoogleSQL

CREATE TABLE Customers (
  CustomerID INT64,
  CreatedAt TIMESTAMP DEFAULT (CURRENT_TIMESTAMP())
) PRIMARY KEY (CustomerID);

Untuk mengetahui informasi selengkapnya, lihat DEFAULT (ekspresi) di "Bahasa definisi data GoogleSQL".

PostgreSQL

CREATE TABLE customers (
  customerid bigint NOT NULL,
  createdat timestamptz DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY(customerid)
  );

Untuk informasi selengkapnya, lihat CREATE TABLE dalam "PostgreSQL data definition language".

TTL pada kolom yang dihasilkan

Kebijakan penghapusan baris dapat menggunakan kolom yang dihasilkan untuk menyatakan aturan yang lebih canggih. Misalnya, Anda dapat menentukan kebijakan penghapusan baris pada stempel waktu greatest (GoogleSQL atau PostgreSQL) dari beberapa kolom, atau memetakan nilai lain ke stempel waktu.

GoogleSQL

Tabel berikut bernama Orders melacak pesanan penjualan. Pemilik tabel ingin menyiapkan kebijakan penghapusan baris yang menghapus pesanan yang dibatalkan setelah 30 hari, dan pesanan yang tidak dibatalkan setelah 180 hari.

TTL Spanner hanya mengizinkan satu kebijakan penghapusan baris per tabel. Untuk menunjukkan dua kriteria dalam satu kolom, Anda dapat menggunakan kolom yang dihasilkan dengan pernyataan IF:

CREATE TABLE Orders (
  OrderId INT64 NOT NULL,
  OrderStatus STRING(30) NOT NULL,
  LastModifiedDate TIMESTAMP NOT NULL,
  ExpiredDate TIMESTAMP AS (IF(OrderStatus = 'Cancelled',
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 30 DAY),
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 180 DAY))) STORED,
) PRIMARY KEY(OrderId),
ROW DELETION POLICY (OLDER_THAN(ExpiredDate, INTERVAL 0 DAY));

Pernyataan ini membuat kolom bernama ExpiredDate yang menambahkan 30 hari atau 180 hari ke LastModifiedDate, bergantung pada status pesanan. Kemudian, kolom ini menentukan kebijakan penghapusan baris untuk mengakhiri masa berlaku baris pada hari yang disimpan di kolom ExpiredDate dengan menentukan INTERVAL 0 day.

PostgreSQL

Tabel berikut bernama Orders melacak pesanan penjualan. Pemilik tabel ingin menyiapkan kebijakan penghapusan baris yang menghapus baris setelah 30 hari tidak aktif.

TTL Spanner hanya mengizinkan satu kebijakan penghapusan baris per tabel. Untuk menunjukkan dua kriteria dalam satu kolom, Anda dapat membuat kolom yang dihasilkan:

CREATE TABLE orders (
    orderid bigint NOT NULL,
    orderstatus varchar(30) NOT NULL,
    createdate timestamptz NOT NULL,
    lastmodifieddate timestamptz,
    expireddate timestamptz GENERATED ALWAYS AS (GREATEST(createdate, lastmodifieddate)) STORED,
    PRIMARY KEY(orderid)
) TTL INTERVAL '30 days' ON expireddate;

Pernyataan ini membuat kolom yang dihasilkan bernama ExpiredDate yang mengevaluasi tanggal terbaru dari dua tanggal tersebut (LastModifiedDate atau CreateDate). Kemudian, pernyataan ini menentukan kebijakan penghapusan baris untuk menghapus baris setelah 30 hari sejak perintah dibuat, atau jika perintah diubah dalam 30 hari tersebut, perintah ini akan memperpanjang penghapusan selama 30 hari lagi.

TTL dan tabel sisipan

Tabel yang diselingi adalah pengoptimalan performa yang mengaitkan baris terkait dalam tabel turunan satu-ke-banyak dengan baris dalam tabel induk. Untuk menambahkan kebijakan penghapusan baris di tabel induk, semua tabel turunan yang diselingi harus menentukan ON DELETE CASCADE, yang berarti baris turunan akan dihapus secara atomik dengan baris induk. Hal ini memastikan integritas referensi sehingga penghapusan pada tabel induk juga menghapus baris turunan terkait dalam transaksi yang sama. TTL Spanner tidak mendukung ON DELETE NO ACTION.

Ukuran transaksi maksimum

Spanner memiliki batas ukuran transaksi. Penghapusan berurutan pada hierarki induk-turunan besar dengan kolom yang diindeks dapat melebihi batas ini dan menyebabkan satu atau beberapa operasi TTL gagal. Untuk operasi yang gagal, TTL akan mencoba lagi dengan batch yang lebih kecil, hingga satu baris induk. Namun, hierarki turunan yang besar bahkan untuk satu baris induk mungkin masih melebihi batas mutasi.

Operasi yang gagal dilaporkan dalam metrik TTL.

Jika satu baris dan turunannya yang diselingi terlalu besar untuk dihapus, Anda dapat melampirkan kebijakan penghapusan baris langsung di tabel turunan, selain kebijakan di tabel induk. Kebijakan pada tabel turunan harus dikonfigurasi sedemikian rupa sehingga baris turunan dihapus sebelum baris induk.

Pertimbangkan untuk melampirkan kebijakan penghapusan baris ke tabel turunan jika dua pernyataan berikut berlaku:

  • Tabel turunan memiliki indeks global yang terkait dengannya; dan
  • Anda mengharapkan banyak baris turunan (>100) per baris induk.

Menghapus kebijakan penghapusan baris

Anda dapat menghapus kebijakan penghapusan baris yang ada dari tabel. Tindakan ini akan menampilkan error jika tidak ada kebijakan penghapusan baris yang ada di tabel.

GoogleSQL

ALTER TABLE MyTable
DROP ROW DELETION POLICY;

PostgreSQL

ALTER TABLE mytable
DROP TTL;

Menghapus kebijakan penghapusan baris akan segera membatalkan proses TTL apa pun yang berjalan di latar belakang. Setiap baris yang telah dihapus oleh proses yang sedang berlangsung akan tetap dihapus.

Menghapus kolom yang dirujuk oleh kebijakan penghapusan baris

Spanner tidak mengizinkan Anda menghapus kolom yang dirujuk oleh kebijakan penghapusan baris. Anda harus menghapus kebijakan penghapusan baris terlebih dahulu sebelum menghapus kolom.

Melihat kebijakan penghapusan baris tabel

Anda dapat melihat kebijakan penghapusan baris tabel Spanner.

GoogleSQL

SELECT TABLE_NAME, ROW_DELETION_POLICY_EXPRESSION
FROM INFORMATION_SCHEMA.TABLES
WHERE ROW_DELETION_POLICY_EXPRESSION IS NOT NULL;

Untuk mengetahui informasi selengkapnya, lihat Skema informasi untuk database dialek GoogleSQL.

PostgreSQL

SELECT table_name, row_deletion_policy_expression
FROM information_schema.tables
WHERE row_deletion_policy_expression is not null;

Untuk informasi selengkapnya, lihat Skema informasi untuk database dialek PostgreSQL.

Mengubah kebijakan penghapusan baris

Anda dapat mengubah kolom atau ekspresi interval kebijakan penghapusan baris yang ada. Contoh berikut mengalihkan kolom dari CreatedAt ke ModifiedAt dan memperluas interval dari 1 DAY ke 7 DAY. Tindakan ini akan menampilkan error jika tidak ada kebijakan penghapusan baris yang ada di tabel.

GoogleSQL

ALTER TABLE MyTable
REPLACE ROW DELETION POLICY (OLDER_THAN(ModifiedAt, INTERVAL 7 DAY));

PostgreSQL

ALTER TABLE mytable
ALTER TTL INTERVAL '7 days' ON timestampcolumn;